package com.qmth.teachcloud.mark.utils;

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

import org.apache.commons.collections4.CollectionUtils;

import com.qmth.boot.core.exception.StatusException;
import org.apache.commons.lang3.StringUtils;

/**
 * 计算器
 *
 * @author
 * @date 2019年7月30日
 * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
 */
public class Calculator {

    /**
     * 加法 保留两位小数
     *
     * @param v1
     * @param v2
     * @return
     */
    public static double add(double v1, double v2) {
        return add(v1, v2, 2);

    }

    /**
     * 加法 保留指定位小数
     *
     * @param v1
     * @param v2
     * @param len
     * @return
     */
    public static double add(double v1, double v2, int len) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.add(b2).setScale(len, BigDecimal.ROUND_HALF_UP).doubleValue();

    }

    /**
     * 加法 保留指定位小数
     *
     * @param ds
     * @param len
     * @return
     */
    public static double add(List<Double> ds, int len) {
        if (CollectionUtils.isEmpty(ds)) {
            throw new StatusException("数组为空");
        }
        BigDecimal ret = new BigDecimal(0.0);
        for (Double d : ds) {
            if (d == null) {
                throw new StatusException("数组元素为空");
            }
            ret = ret.add(new BigDecimal(d));
        }
        return ret.setScale(len, BigDecimal.ROUND_HALF_UP).doubleValue();

    }

    /**
     * 减法 保留两位小数
     *
     * @param v1
     * @param v2
     * @return
     */
    public static double subtract(double v1, double v2) {
        return subtract(v1, v2, 2);

    }

    /**
     * 减法 保留指定位小数
     *
     * @param v1
     * @param v2
     * @param len
     * @return
     */
    public static double subtract(double v1, double v2, int len) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.subtract(b2).setScale(len, BigDecimal.ROUND_HALF_UP).doubleValue();

    }

    /**
     * 差值绝对值
     *
     * @param v1
     * @param v2
     * @param len
     * @return
     */
    public static double absoluteDiff(double v1, double v2, int len) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        if (v1 > v2) {
            return b1.subtract(b2).setScale(len, BigDecimal.ROUND_HALF_UP).doubleValue();
        } else {
            return b2.subtract(b1).setScale(len, BigDecimal.ROUND_HALF_UP).doubleValue();
        }

    }

    /**
     * 乘法
     *
     * @param v1
     * @param v2
     * @return
     */
    public static double multiply(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.multiply(b2).doubleValue();
    }

    /**
     * 乘法 保留指定位小数
     *
     * @param v1
     * @param v2
     * @param len
     * @return
     */
    public static double multiply(double v1, double v2, int len) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.multiply(b2).setScale(len, BigDecimal.ROUND_HALF_UP).doubleValue();

    }


    /**
     * 除法 保留两位小数
     *
     * @param v1
     * @param v2
     * @return
     */
    public static double divide(double v1, double v2) {
        return divide(v1, v2, 2);
    }

    /**
     * 除法 保留指定位小数
     *
     * @param v1
     * @param v2
     * @param len
     * @return
     */
    public static double divide(double v1, double v2, int len) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.divide(b2, len, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public static String divide2String(Double v1, Double v2, int len) {
        if (v1 == null || v2 == null || v2 == 0) {
            return "0";
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.divide(b2, len, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString();
    }

    public static Double round(Double value, int length) {
        if (value == null) {
            return null;
        }
        return new BigDecimal(value).setScale(length, RoundingMode.HALF_UP).doubleValue();
    }

    public static String round(String value, int length) {
        if (StringUtils.isBlank(value)) {
            return null;
        }
        return new BigDecimal(value).setScale(length, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
    }
}
