package com.infoepoch.pms.dispatchassistant.common.utils;

import java.math.BigDecimal;
import java.util.Optional;

public class BigDecimalUtils {
    // 百
    public final static BigDecimal HUNDRED = new BigDecimal("100");
    // 千
    public final static BigDecimal THOUSAND = new BigDecimal("1000");
    // 万
    public final static BigDecimal WAN = new BigDecimal("10000");
    // 亿
    public final static BigDecimal YI = new BigDecimal("100000000");
    // 默认统一精度——4
    public final static int SCALE = 4;
    // 默认精度取舍类型——四舍五入
    public final static int ROUND_TYPE = BigDecimal.ROUND_HALF_UP;
    public final static BigDecimal five = new BigDecimal("0.5");

    /**
     * String字符串转换成BigDecimal
     *
     * @param str
     * @return
     */
    public static BigDecimal transferString(String str) {
        try {
            return new BigDecimal(str);
        } catch (Exception e) {
            return BigDecimal.ZERO;
        }
    }

    /**
     * 乘以一百
     * 入参为null时返回0
     *
     * @param decimal
     * @return
     */
    public static BigDecimal multiplyHundred(BigDecimal decimal) {
        if (Optional.ofNullable(decimal).isPresent())
            return decimal.multiply(HUNDRED).setScale(SCALE, ROUND_TYPE);
        return BigDecimal.ZERO;
    }

    /**
     * 乘以一千
     * 入参为null时返回0
     *
     * @param decimal
     * @return
     */
    public static BigDecimal multiplyThousand(BigDecimal decimal) {
        if (Optional.ofNullable(decimal).isPresent())
            return decimal.multiply(THOUSAND).setScale(SCALE, ROUND_TYPE);
        return BigDecimal.ZERO;
    }

    /**
     * 乘以一万
     * 入参为null时返回0
     *
     * @param decimal
     * @return
     */
    public static BigDecimal multiplyWan(BigDecimal decimal) {
        if (Optional.ofNullable(decimal).isPresent())
            return decimal.multiply(WAN).setScale(SCALE, ROUND_TYPE);
        return BigDecimal.ZERO;
    }

    /**
     * 乘以一亿
     *
     * @param decimal
     * @return
     */
    public static BigDecimal multiplyYi(BigDecimal decimal) {
        if (Optional.ofNullable(decimal).isPresent())
            return decimal.multiply(YI).setScale(SCALE, ROUND_TYPE);
        return BigDecimal.ZERO;
    }

    /**
     * 除以一百
     * 入参为null时返回0
     *
     * @param decimal
     * @return
     */
    public static BigDecimal divideHundred(BigDecimal decimal, int roundType) {
        if (Optional.ofNullable(decimal).isPresent())
            return decimal.divide(HUNDRED, SCALE, roundType < 0 ? ROUND_TYPE : roundType);
        return BigDecimal.ZERO;
    }

    /**
     * 除以一千
     * 入参为null时返回0
     *
     * @param decimal
     * @return
     */
    public static BigDecimal divideThousand(BigDecimal decimal, int roundType) {
        if (Optional.ofNullable(decimal).isPresent())
            return decimal.divide(THOUSAND, SCALE, roundType < 0 ? ROUND_TYPE : roundType);
        return BigDecimal.ZERO;
    }

    /**
     * 除以一万
     * 入参为null时返回0
     *
     * @param decimal
     * @return
     */
    public static BigDecimal divideWan(BigDecimal decimal, int roundType) {
        if (Optional.ofNullable(decimal).isPresent())
            return decimal.divide(WAN, SCALE, roundType < 0 ? ROUND_TYPE : roundType);
        return BigDecimal.ZERO;
    }

    /**
     * 除以一亿
     *
     * @param decimal
     * @param roundType
     * @return
     */
    public static BigDecimal divideYi(BigDecimal decimal, int roundType) {
        if (Optional.ofNullable(decimal).isPresent())
            return decimal.divide(YI, SCALE, roundType < 0 ? ROUND_TYPE : roundType);
        return BigDecimal.ZERO;
    }

    /**
     * bigdecimal转换成String
     *
     * @param decimal
     * @return
     */
    public static String decimalToString(BigDecimal decimal) {
        if (Optional.ofNullable(decimal).isPresent())
            return decimal.toString();
        return "";
    }

    public static BigDecimal getDecimal(Object object) {
        if(object == null)
            return BigDecimal.ZERO;
        BigDecimal decimal;
        try {
            decimal = (BigDecimal) object;
        } catch (Exception e) {
            decimal = new BigDecimal(String.valueOf(object));
        }
        return decimal;
    }

    /**
     * 获取BigDecimal类型对象，为null时返回BigDecimal.ZERO
     *
     * @param integer
     * @return
     */
    public static BigDecimal getDecimal(Integer integer) {
        return integer == null ? BigDecimal.ZERO : new BigDecimal(String.valueOf(integer));
    }

    /**
     * 获取BigDecimal类型对象，为null时返回BigDecimal.ZERO
     *
     * @param decimal
     * @return
     */
    public static BigDecimal getDecimal(BigDecimal decimal) {
        return decimal == null ? BigDecimal.ZERO : decimal;
    }

    /**
     * 获取BigDecimal对象
     *
     * @param object
     * @return
     */
    public static BigDecimal getDecimalByObject(Object object) {
        return getDecimalByObject(object, BigDecimal.ZERO);
    }

    /**
     * 获取BigDecimal对象
     *
     * @param object
     * @param defaultDecimal 默认值
     * @return
     */
    public static BigDecimal getDecimalByObject(Object object, BigDecimal defaultDecimal) {
        try {
            return object == null ? BigDecimal.ZERO : new BigDecimal(String.valueOf(object));
        } catch (Exception e) {
            return defaultDecimal;
        }
    }

    /**
     * 获取bigDecimal的绝对值
     *
     * @param decimal
     * @return
     */
    public static BigDecimal getAbsoluteDecimal(BigDecimal decimal) {
        return decimal == null ? BigDecimal.ZERO : decimal.abs();
    }

    /**
     * 获取BigDecimal类型对象，异常时返回BigDecimal.ZERO
     *
     * @param decimalStr
     * @return
     */
    public static BigDecimal getDecimal(String decimalStr) {
        BigDecimal decimal;
        try {
            decimal = new BigDecimal(decimalStr);
        } catch (Exception e) {
            decimal = BigDecimal.ZERO;
        }
        return decimal;
    }

    public static BigDecimal getDecimal(String decimalStr, BigDecimal defaultDecimal) {
        BigDecimal decimal;
        try {
            decimal = new BigDecimal(decimalStr);
        } catch (Exception e) {
            decimal = defaultDecimal;
        }
        return decimal;
    }

    public static BigDecimal addTwoBigDecimal(BigDecimal thisDecimal, BigDecimal thatDecimal) {
        return Optional.ofNullable(thisDecimal).orElse(BigDecimal.ZERO).add(Optional.ofNullable(thatDecimal).orElse(BigDecimal.ZERO));
    }

    public static String addTwoBigDecimalTwo(String thisDecimalStr, String thatDecimalStr) {
        BigDecimal thisDecimal = new BigDecimal(thisDecimalStr);
        BigDecimal thatDecimal = new BigDecimal(thatDecimalStr);
        return addTwoBigDecimal(thisDecimal, thatDecimal).toString();
    }

    public static BigDecimal subtractTwoBigDecimal(BigDecimal total, BigDecimal subtract) {
        return getDecimal(total).subtract(getDecimal(subtract));
    }

    /**
     * 处理两个BigDecimal对象的除法
     *
     * @param molecule
     * @param denominator
     * @param scale
     * @param roundType
     * @return
     */
    public static BigDecimal divideTwoDecimal(BigDecimal molecule, BigDecimal denominator, int scale, int roundType) {
        if (molecule == null || denominator == null)
            return BigDecimal.ZERO;
        if (denominator.compareTo(BigDecimal.ZERO) == 0)
            return BigDecimal.ZERO;
        return molecule.divide(denominator, scale, roundType);
    }

    /**
     * 获取BigDecimal列表中的最大值
     *
     * @param decimals
     * @return
     */
    public static BigDecimal getMaxBigDecimal(BigDecimal... decimals) {
        BigDecimal max = BigDecimal.ZERO;
        for (BigDecimal decimal : decimals) {
            if (max.compareTo(decimal) < 0) {
                max = decimal;
            }
        }
        return max;
    }

    /**
     * 校验value是否是0.5的倍数
     * @param value
     * @return
     */
    public static boolean checkFiveMultiple(BigDecimal value){
        // 计算value除以0.5后的余数
        BigDecimal remainder = value.remainder(five);
        // 如果余数为0，则value是0.5的倍数
        return remainder.compareTo(BigDecimal.ZERO) == 0;
    }
}
