package com.jjt.rz;

import com.jjt.JjtApplication;
import com.jjt.ws.domain.TwinRzCalcMonth;
import com.jjt.ws.service.ITwinRzCalcMonthService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;

/**
 * DataProcess$
 *
 * @author wukai
 * @date 2024/5/7 11:49
 */
@SpringBootTest(classes = JjtApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class RzCalcTest {
    @Resource
    private ITwinRzCalcMonthService rzCalcMonthService;

    @Test
    public void test() {
        TwinRzCalcMonth calcMonth = new TwinRzCalcMonth();
        Map<String, Object> params = new HashMap<>();
        params.put("start", LocalDate.now().minusDays(30).toString());
        calcMonth.setParams(params);
        List<TwinRzCalcMonth> list = rzCalcMonthService.selectTwinRzCalcMonthList(calcMonth);
        list.size();
    }
    private static final Random random = new Random();
    private static final int SCALE = 2; // 保留小数位数
    private static final double DEVIATION_PERCENT = 0.25; // 波动幅度30%

    public static void main(String[] args) {
        BigDecimal total = new BigDecimal("100.00");
        int parts = 8;

        BigDecimal[] result = balancedRandomSplit(total, parts);
        System.out.println("分割结果: " + Arrays.toString(result));

        BigDecimal sum = Arrays.stream(result)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        System.out.println("验证总和: " + sum);
    }

    public static BigDecimal[] balancedRandomSplit(BigDecimal total, int parts) {
        if (parts <= 0) throw new IllegalArgumentException("份数必须大于0");
        if (total.compareTo(BigDecimal.ZERO) <= 0) throw new IllegalArgumentException("总数必须大于0");

        BigDecimal average = total.divide(new BigDecimal(parts), SCALE, RoundingMode.HALF_UP);
        BigDecimal[] splits = new BigDecimal[parts];
        BigDecimal remaining = total;

        // 前parts-1次分割
        for (int i = 0; i < parts - 1; i++) {
            // 计算允许的波动范围
            BigDecimal min = average.multiply(BigDecimal.ONE.subtract(new BigDecimal(DEVIATION_PERCENT)))
                    .max(BigDecimal.ZERO);
            BigDecimal max = average.multiply(BigDecimal.ONE.add(new BigDecimal(DEVIATION_PERCENT)));

            // 确保剩余金额足够
            BigDecimal adjustedMax = remaining.subtract(min.multiply(new BigDecimal(parts - i - 1)));
            max = max.min(adjustedMax);

            // 在范围内随机取值
            BigDecimal range = max.subtract(min);
            BigDecimal randomFactor = BigDecimal.valueOf(random.nextDouble());
            BigDecimal split = min.add(range.multiply(randomFactor))
                    .setScale(SCALE, RoundingMode.HALF_UP);

            splits[i] = split;
            remaining = remaining.subtract(split);
        }

        // 最后一份
        splits[parts - 1] = remaining.setScale(SCALE, RoundingMode.HALF_UP);

        return splits;
    }
}
