package com.tofly.feesapi.common;

import org.springframework.beans.BeanWrapperImpl;

import java.beans.PropertyDescriptor;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

public class NumberHelper {

    private static final String[] DIGITS = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
    private static final String[] UNITS = {"", "拾", "佰", "仟"};
    private static final String[] BIG_UNITS = {"", "万", "亿"};

    public static String toChineseMoney(BigDecimal amount) {
        if (amount == null) {
            return "零元整";
        }

        // 处理负数
        boolean isNegative = amount.compareTo(BigDecimal.ZERO) < 0;
        amount = isNegative ? amount.negate() : amount;

        // 四舍五入到分
        amount = amount.setScale(2, BigDecimal.ROUND_HALF_UP);

        // 分离整数和小数部分
        long yuan = amount.longValue();
        int fen = amount.multiply(new BigDecimal(100)).intValue() % 100;
        int jiao = fen / 10;
        fen = fen % 10;

        StringBuilder result = new StringBuilder();

        // 处理负数
        if (isNegative) {
            result.append("负");
        }

        // 处理整数部分
        if (yuan == 0) {
            result.append("零");
        } else {
            result.append(convertIntegerPart(yuan));
        }
        result.append("元");

        // 处理小数部分
        if (jiao == 0 && fen == 0) {
            result.append("整");
        } else {
            if (jiao > 0) {
                result.append(DIGITS[jiao]).append("角");
            }
            if (fen > 0) {
                result.append(DIGITS[fen]).append("分");
            }
        }

        return result.toString();
    }

    private static String convertIntegerPart(long number) {
        if (number == 0) {
            return DIGITS[0];
        }

        StringBuilder result = new StringBuilder();
        int unitIndex = 0;

        while (number > 0) {
            long group = number % 10000;
            String groupStr = convertGroup(group);

            if (!groupStr.isEmpty()) {
                groupStr += BIG_UNITS[unitIndex];
                result.insert(0, groupStr);
            }

            number /= 10000;
            unitIndex++;
        }

        // 处理连续的零
        String res = result.toString();
        res = res.replaceAll("零+", "零");
        res = res.replaceAll("^零", "");
        res = res.replaceAll("零$", "");

        return res.isEmpty() ? DIGITS[0] : res;
    }

    private static String convertGroup(long group) {
        if (group == 0) {
            return DIGITS[0];
        }

        StringBuilder sb = new StringBuilder();
        int[] digits = new int[4];
        for (int i = 0; i < 4; i++) {
            digits[i] = (int) (group % 10);
            group /= 10;
        }

        boolean hasNonZero = false;
        for (int i = 3; i >= 0; i--) {
            if (digits[i] != 0) {
                sb.append(DIGITS[digits[i]]).append(UNITS[i]);
                hasNonZero = true;
            } else if (hasNonZero && i > 0 && digits[i - 1] != 0) {
                sb.append(DIGITS[0]);
            }
        }

        return sb.toString();
    }

    public static String CmycurD(BigDecimal num) {
        String str1 = "零壹贰叁肆伍陆柒捌玖";            //0-9所对应的汉字
        String str2 = "万仟佰拾亿仟佰拾万仟佰拾元角分"; //数字位所对应的汉字
        String str3 = "";    //从原num值中取出的值
        String str4 = "";    //数字的字符串形式
        String str5 = "";  //人民币大写金额形式
        int i;    //循环变量
        int j;    //num的值乘以100的字符串长度
        String ch1 = "";    //数字的汉语读法
        String ch2 = "";    //数字位的汉字读法
        int nzero = 0;  //用来计算连续的零值是几个
        int temp;            //从原num值中取出的值

        str4 = num.multiply(new BigDecimal(100)).setScale(0, RoundingMode.DOWN).toString();        //将num乘100并转换成字符串形式
        j = str4.length();      //找出最高位
        if (j > 15) {
            return "溢出";
        }
        str2 = str2.substring(15 - j);   //取出对应位数的str2的值。如：200.55,j为5所以str2=佰拾元角分

        //循环取出每一位需要转换的值
        for (i = 0; i < j; i++) {
            str3 = str4.substring(i, i + 1);          //取出需转换的某一位的值
            temp = Integer.valueOf(str3);      //转换为数字
            if (i != (j - 3) && i != (j - 7) && i != (j - 11) && i != (j - 15)) {
                //当所取位数不为元、万、亿、万亿上的数字时
                if (str3 == "0") {
                    ch1 = "";
                    ch2 = "";
                    nzero = nzero + 1;
                } else {
                    if (str3 != "0" && nzero != 0) {
                        ch1 = "零" + str1.substring(temp, temp + 1);
                        ch2 = str2.substring(i, i + 1);
                        nzero = 0;
                    } else {
                        ch1 = str1.substring(temp, temp + 1);
                        ch2 = str2.substring(i, i + 1);
                        nzero = 0;
                    }
                }
            } else {
                //该位是万亿，亿，万，元位等关键位
                if (str3 != "0" && nzero != 0) {
                    ch1 = "零" + str1.substring(temp, temp + 1);
                    ch2 = str2.substring(i, i + 1);
                    nzero = 0;
                } else {
                    if (str3 != "0" && nzero == 0) {
                        ch1 = str1.substring(temp, temp + 1);
                        ch2 = str2.substring(i, i + 1);
                        nzero = 0;
                    } else {
                        if (str3 == "0" && nzero >= 3) {
                            ch1 = "";
                            ch2 = "";
                            nzero = nzero + 1;
                        } else {
                            if (j >= 11) {
                                ch1 = "";
                                nzero = nzero + 1;
                            } else {
                                ch1 = "";
                                ch2 = str2.substring(i, i + 1);
                                nzero = nzero + 1;
                            }
                        }
                    }
                }
            }
            if (i == (j - 11) || i == (j - 3)) {
                //如果该位是亿位或元位，则必须写上
                ch2 = str2.substring(i, i + 1);
            }
            str5 = str5 + ch1 + ch2;

            if (i == j - 1 && str3 == "0") {
                //最后一位（分）为0时，加上“整”
                str5 = str5 + '整';
            }
        }
        if (num == BigDecimal.ZERO) {
            str5 = "零元整";
        }
        return str5;
    }

    public static String[] getNullPropertyNames(Object source) {
        final BeanWrapperImpl beanWrapper = new BeanWrapperImpl(source);
        PropertyDescriptor[] pds = beanWrapper.getPropertyDescriptors();
        List<String> nullPropertyNames = new ArrayList<>();
        for (PropertyDescriptor pd : pds) {
            if (beanWrapper.getPropertyValue(pd.getName()) == null) {
                nullPropertyNames.add(pd.getName());
            }
        }
        return nullPropertyNames.toArray(new String[0]);
    }
}
