package com.tmerclub.cloud.common.util;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.constant.RetainedDateType;

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

/**
 * @author TRACK
 */
public class AnalysisUtil {

    public static final double LOW_RATE = -100.0;

    private AnalysisUtil() {
    }

    public static Double handleLong(Long value) {
        if (Objects.isNull(value)) {
            return 0.00;
        }
        return PriceUtil.toDecimalPrice(value).doubleValue();
    }

    public static Double getDouble(Double value) {
        if (Objects.isNull(value)) {
            return 0.0;
        }
        return value;
    }


    public static Double handleDouble(Double value) {
        if (Objects.isNull(value)) {
            return 0.00;
        }
        return value;
    }

    public static Double divAverage(Integer a, Integer h, Integer scale) {
        if (Objects.isNull(h) || 0 == h || Objects.isNull(a)) {
            return 0.0;
        }
        return Arith.div(a, h, scale);
    }

    public static Double divAverage(Double a, Integer h, Integer scale) {
        if (Objects.isNull(h) || 0 == h || Objects.isNull(a)) {
            return 0.0;
        }
        return Arith.div(a, h, scale);
    }

    public static Double divAverage(Double a, Double h, Integer scale) {
        if (Objects.isNull(h) || 0 == h || Objects.isNull(a)) {
            return 0.0;
        }
        return Arith.div(a, h, scale);
    }


    public static Double setRate(Double newNum, Double oldNum) {
        if (newNum.equals(0.0) && oldNum.equals(0.0)) {
            return 0.0;
        } else if (0.0 < newNum && oldNum.equals(0.0)) {
            return 0.0;
        } else if (newNum.equals(0.0) && 0.0 < oldNum) {
            return LOW_RATE;
        }
        double sub = Arith.sub(newNum, oldNum);
        return Arith.mul(Arith.div(sub, oldNum, 2), 100);
    }

    /**
     * @param a dividend
     * @param h divisor
     * @return 向上取整
     */
    public static int ceil(int a, int h) {
        if (0 == a || 0 == h) {
            return 0;
        }
        BigDecimal dividend = new BigDecimal(Integer.toString(a));
        BigDecimal divisor = new BigDecimal(Integer.toString(h));
        BigDecimal divide = dividend.divide(divisor, 0, RoundingMode.UP);
        return divide.intValue();
    }

    /**
     * 计算百分比
     *
     * @param a          被除数
     * @param sub          除数
     * @return 放大倍数后的数值
     */
    public static BigDecimal calculatePercentage(Integer a, Integer sub) {
        // 保留小数位默认为2， 放大倍数默认为100
        return calculatePercentage(a, sub, 2, 100);
    }

    /**
     * 计算百分比
     *
     * @param a          被除数
     * @param sub          除数
     * @param scale      保留小数位
     * @param percentage 放大倍数
     * @return 放大倍数后的数值
     */
    public static BigDecimal calculatePercentage(Integer a, Integer sub, int scale, Integer percentage) {

        boolean isCalculate = Objects.isNull(a) || Objects.isNull(sub) || Objects.isNull(percentage) ||
                a.compareTo(0) == 0 || sub < 0 || percentage.compareTo(0) == 0;
        if (isCalculate) {
            return new BigDecimal("0");
        }
        BigDecimal bigDecimal = new BigDecimal(a.toString());
        BigDecimal divisor = new BigDecimal(sub.toString());
        BigDecimal multiplicand = new BigDecimal(percentage.toString());
        return bigDecimal.multiply(multiplicand).divide(divisor, scale, RoundingMode.HALF_UP);
    }

    /**
     * 获取时间范围内的所有时间
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return yyyy-MM 的时间字符串列表
     */
    public static List<String> getRangeDate(Date startTime, Date endTime) {
        List<DateTime> dateTimes = DateUtil.rangeToList(DateUtil.beginOfMonth(startTime), endTime, DateField.MONTH);
        List<String> list = new ArrayList<>(1);
        for (DateTime dateTime : dateTimes) {
            list.add(DateUtil.format(dateTime, "yyyy-MM"));
        }
        // 控制月在最近 3 、6、 12个月
        int size = list.size();
        boolean isReduce = size == RetainedDateType.THREE_MONTH.getMonthNum() + 1 ||
                size == RetainedDateType.SIX_MONTH.getMonthNum() + 1 ||
                size == RetainedDateType.ONE_YEAR.getMonthNum() + 1;
        if (isReduce) {
            list.remove(list.get(0));
        }
        return list;
    }

    /**
     * 金额Long格式转换Double
     * @param num
     * @return 金额字符串
     */
    public static String conversionPrices(String num) {
        if (StrUtil.isBlank(num)) {
            return num;
        }
        BigDecimal b1 = new BigDecimal(num);
        BigDecimal b2 = new BigDecimal(Constant.PRICE_MAGNIFICATION);
        double price = b1.divide(b2, 2, RoundingMode.HALF_UP).doubleValue();
        return Double.toString(price);
    }

    public static Double getDefault(Double value) {
        if (Objects.nonNull(value)) {
            return value;
        }
        return 0.0D;
    }

    public static Integer getDefault(Integer value) {
        if (Objects.nonNull(value)) {
            return value;
        }
        return Constant.ZERO_INTEGER;
    }
}
