package com.ruoyi.common.utils;

import cn.hutool.core.util.NumberUtil;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;

public final class NumUtils
{
    public static BigDecimal[] percentage(BigDecimal b, int scale, BigDecimal...as)
    {
        if(null == as || as.length == 0)
            return new BigDecimal[0];

        BigDecimal[] res = new BigDecimal[as.length];
        BigDecimal remain = new BigDecimal("100");
        for(int i = 0; i < as.length; i++)
        {
            BigDecimal a = as[i];
            if(isZero_s(a) || remain.compareTo(BigDecimal.ZERO) < 0)
                res[i] = BigDecimal.ZERO;
            else
            {
                BigDecimal percentage = percentage(a, b, scale);
                BigDecimal min = NumberUtil.min(remain, percentage);
                remain = remain.subtract(percentage);
                res[i] = min;
            }
        }
        return res;
    }

    public static BigDecimal[] percentage(long total, int scale, long...as)
    {
        if(null == as || as.length == 0)
            return new BigDecimal[0];

        BigDecimal[] res = new BigDecimal[as.length];
        BigDecimal b = BigDecimal.valueOf(total);
        BigDecimal remain = new BigDecimal("100");
        long remainL = total;
        for(int i = 0; i < as.length; i++)
        {
            BigDecimal a = BigDecimal.valueOf(as[i]);
            if(isZero_s(a) || remainL <= 0)
                res[i] = BigDecimal.ZERO;
            else
            {
                if(as[i] == remainL) // 无剩余
                {
                    res[i] = remain;
                    remain = BigDecimal.ZERO;
                }
                else
                {
                    BigDecimal percentage = percentage(a, b, scale);
                    remain = remain.subtract(percentage);
                    res[i] = percentage;
                }
                remainL -= as[i];
            }
        }
        return res;
    }

    public static BigDecimal[] percentage(int scale, long...as)
    {
        return percentage(Arrays.stream(as).sum(), scale, as);
    }

    public static BigDecimal percentage(BigDecimal a, BigDecimal b, int scale)
    {
        if(isZero_s(a) || isZero_s(b))
            return BigDecimal.ZERO;

        return a.multiply(new BigDecimal("100")).divide(b, scale, RoundingMode.UP);
    }

    public static boolean isZero_s(BigDecimal b)
    {
        return null == b || BigDecimal.ZERO.compareTo(b) == 0;
    }

    public static BigDecimal scale_s(BigDecimal b, int scale)
    {
        if(isZero_s(b))
            return BigDecimal.ZERO;
        return b.setScale(scale, RoundingMode.UP);
    }

    public static BigDecimal scale2_s(BigDecimal b)
    {
        return scale_s(b, 2);
    }

    public static BigDecimal scale4_s(BigDecimal b)
    {
        return scale_s(b, 4);
    }

    public static BigDecimal scale0_s(BigDecimal b)
    {
        return scale_s(b, 0);
    }

    private NumUtils() {}
}
