package com.malk.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.regex.Pattern;

/**
 * 数字格式化
 * -
 * ppExt: 不要直接使用 Number 作为类型, 不同基本类型比较值时会有偏差 [可以作为父类接受数据, 避免直接强制类型转换错误, 再进行基本类型处理]
 */
@Slf4j
public class UtilNumber {

    /**
     * 货币格式化
     */
    public static final String formatCurrency(Number number) {
        DecimalFormat curFormat = (DecimalFormat) NumberFormat.getCurrencyInstance(Locale.CHINA);
        return curFormat.format(number);
    }

    /**
     * 去除CHY货币标识
     */
    public static final String replaceCurrencyCHY(String cur) {
        return cur.replace("￥", "").replace("¥", "");
    }

    /**
     * 判断是否数字
     */
    public static boolean matchNumber(String num) {
        Pattern pattern = Pattern.compile("^-?\\d+(\\.\\d+)?$");
        return pattern.matcher(num).matches();
    }

    /**
     * 去除CHY货币标识
     */
    public static final BigDecimal replaceCurrencyCHYToDecimal(String cur) {
        String num = replaceCurrencyCHY(cur);
        if (StringUtils.isBlank(num) || !matchNumber(num)) {
            num = "0";
        }
        return new BigDecimal(num);
    }

    /**
     * 百分比格式化
     */
    public static final String formatPercent(Number number) {
        DecimalFormat percentFormat = (DecimalFormat) NumberFormat.getPercentInstance(Locale.CHINA);
        percentFormat.setMinimumFractionDigits(2);
        return percentFormat.format(number);
    }

    /**
     * 小数位精度格式
     */
    public static final String formatPrecisionString(double number) {
        return formatPrecisionString(number, "#.00");
    }

    /**
     * 小数位精度格式
     */
    public static final String formatPrecisionString(double number, String pattern) {
        DecimalFormat df = new DecimalFormat(pattern);
        return df.format(new BigDecimal(number));
    }

    /**
     * 小数位精度格式
     */
    public static final double formatPrecisionValue(double number) {
        return Double.valueOf(formatPrecisionString(number));
    }

    /**
     * 小数位精度格式
     */
    public static final double formatPrecisionValue(float number) {
        return Double.valueOf(formatPrecisionString(number));
    }

    /**
     * 小数位精度格式
     */
    public static final String formatPrecisionString(float number) {
        return formatPrecisionString(Double.valueOf(String.valueOf(number)));
    }

    /**
     * 非数值型字符串, 空字符串兼容
     */
    public static final BigDecimal setBigDecimal(String strNum) {
        BigDecimal decimal = null; // 空
        if (StringUtils.isNotBlank(strNum)) {
            try {
                decimal = new BigDecimal(strNum);
            } catch (NumberFormatException e) {
                decimal = BigDecimal.ZERO;
            }
        }
        return decimal;
    }

    /**
     * 判断两个字符串, 转数值后是否相等
     */
    public static final int compareBigDecimal(String n1, String n2) {
        return setBigDecimal(n1).compareTo(setBigDecimal(n2));
    }

    /**
     * 判断两个字符串, 转数值后是否相等
     */
    public static final boolean equalBigDecimal(String n1, String n2) {
        return compareBigDecimal(n1, n2) == 0;
    }

    /**
     * 判断两个BigDecimal, 转数值后是否相等
     */
    public static final int compareBigDecimal(BigDecimal n1, BigDecimal n2) {
        return n1.compareTo(n2);
    }

    /**
     * 判断两个BigDecimal, 转数值后是否相等
     */
    public static final boolean equalBigDecimal(BigDecimal n1, BigDecimal n2) {
        return compareBigDecimal(n1, n2) == 0;
    }

    /**
     * 尾数: 0.5取整逻辑, 小于0.5为0.5, 大于0.5为1
     */
    public static double roundHalf(double num) {
        double half = num % 1;
        if (half != 0 && half != 0.5) {
            if (half > 0.5f) {
                num = Math.floor(num) + 1.0f;
            } else {
                num = Math.floor(num) + 0.5f;
            }
        }
        return num;
    }
}
