package com.slodon.b2b2c.core.util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

/**
 * 微信红包随机金额算法
 */
public class RedBagUtils {

    public static List<BigDecimal> list = new ArrayList<>();

    public static void main(String[] args) {
        System.out.println(genRedPacket(new BigDecimal("1.00"), new BigDecimal("20.00"), new BigDecimal("500.00"), 100));
    }

    /**
     * 创建一个在范围内的随机数
     *
     * @param lowAmount
     * @param highAmount
     * @return
     */
    public static BigDecimal createRandomKey(BigDecimal lowAmount, BigDecimal highAmount) {
        BigDecimal randomNumber, result = BigDecimal.ZERO;
        //生成随机数
        randomNumber = BigDecimal.valueOf(Math.random());
        //随机生成结果
        result = randomNumber.multiply(highAmount.subtract(lowAmount)).add(lowAmount);
        //保留两位小数,四舍五入
        return result.setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 分配红包
     *
     * @param total 总金额
     * @param count 分配数量
     * @return
     */
    public static List<BigDecimal> genRedPacket(BigDecimal total, int count) {
        BigDecimal b1 = total;
        BigDecimal b2 = new BigDecimal(count);
        for (int i = 0; i < count; i++) {
            String s = String.valueOf((new BigDecimal(Math.random()).multiply(total.add(new BigDecimal(1))).setScale(2, RoundingMode.HALF_UP)).add(
                    (new BigDecimal((Math.random() * 100)).add(new BigDecimal(1))).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP)));
            BigDecimal b3 = new BigDecimal(s);
            list.add(b3);
        }
        assignAmount(b1, b2);
        System.out.println(list);
        return list;
    }

    public static void assignAmount(BigDecimal b1, BigDecimal b2) {
        if (currentAmount(list).doubleValue() < b1.doubleValue()) {
            BigDecimal b3 = currentAmount(list);
            BigDecimal b4 = b1.subtract(b3);
            int i = 0;
            list.set(i = (int) (Math.random() * (b2.intValue())), list.get(i).add(b4));
        } else if (currentAmount(list).doubleValue() > b1.doubleValue()) {
            BigDecimal b3 = currentAmount(list);
            BigDecimal b4 = b3.subtract(b1).divide(b2, 2, RoundingMode.HALF_UP);
            for (int i = 0; i < list.size(); i++) {
                if (list.get(i).doubleValue() > b4.doubleValue()) {
                    list.set(i, list.get(i).subtract(b4));
                }
            }
        }
        if (currentAmount(list).doubleValue() > b1.doubleValue()) {
            BigDecimal b3 = currentAmount(list);
            BigDecimal b4 = b3.subtract(b1);
            for (int i = 0; i < list.size(); i++) {
                if (list.get(i).doubleValue() > b4.doubleValue()) {
                    list.set(i, list.get(i).subtract(b4));
                }
            }
            assignAmount(b1, b2);
        }
    }

    public static BigDecimal currentAmount(List<BigDecimal> list) {
        BigDecimal b = new BigDecimal("0.00");
        for (int i = 0; i < list.size(); i++) {
            b = b.add(list.get(i));
        }
        return b;
    }


    /**
     * 分配红包
     *
     * @param minAmount   最小金额
     * @param maxAmount   最大金额
     * @param totalAmount 总金额
     * @param count       分配数量
     * @return
     */
    public static List<BigDecimal> genRedPacket(BigDecimal minAmount, BigDecimal maxAmount, BigDecimal totalAmount, int count) {
        List<BigDecimal> arrayList = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            //保护值
            BigDecimal protectValue = new BigDecimal(count - i - 1).multiply(minAmount);
            //可支配金额
            BigDecimal disposableAmount = totalAmount.subtract(protectValue);
            if (disposableAmount.compareTo(maxAmount) < 0) {
                maxAmount = disposableAmount;
            }
            BigDecimal result = restRound(minAmount, maxAmount, i, disposableAmount, count - 1);
            if (result.compareTo(minAmount) < 0) {
                result = minAmount;
            }
            totalAmount = totalAmount.subtract(result);
            arrayList.add(result);
        }
        return arrayList;
    }

    public static BigDecimal restRound(BigDecimal min, BigDecimal max, int i, BigDecimal money, int count) {
        BigDecimal redpac;
        if (i == count - 1) {
            redpac = money;
        } else {
            redpac = BigDecimal.valueOf(Math.random()).multiply((max.subtract(min)).add(min));
        }
        return redpac.setScale(2, RoundingMode.HALF_UP);
    }

}
