package org.dromara.payment.util;

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

/**
 * 个人所得税计算工具类（综合所得年度税率表版）
 * 支持根据累计收入、月份、已预缴税额计算当月应预扣税额
 */
public class TaxCalculatorUtils {

    // 每月减除费用（5000元，年度累计为 5000 * n）
    private static final BigDecimal MONTHLY_DEDUCTION = new BigDecimal("5000");
    // 收入减除比例（20%，适用于劳务报酬等综合所得）
    private static final BigDecimal INCOME_DEDUCTION_RATIO = new BigDecimal("0.2");

    // 定义年度税率表（数组形式，每个元素包含：级距上限、税率、速算扣除数）
    private static final List<TaxRate> ANNUAL_TAX_RATES = new ArrayList<>();
    static {
        ANNUAL_TAX_RATES.add(new TaxRate(new BigDecimal("36000"), new BigDecimal("0.03"), new BigDecimal("0")));
        ANNUAL_TAX_RATES.add(new TaxRate(new BigDecimal("144000"), new BigDecimal("0.10"), new BigDecimal("2520")));
        ANNUAL_TAX_RATES.add(new TaxRate(new BigDecimal("300000"), new BigDecimal("0.20"), new BigDecimal("16920")));
        ANNUAL_TAX_RATES.add(new TaxRate(new BigDecimal("420000"), new BigDecimal("0.25"), new BigDecimal("31920")));
        ANNUAL_TAX_RATES.add(new TaxRate(new BigDecimal("660000"), new BigDecimal("0.30"), new BigDecimal("52920")));
        ANNUAL_TAX_RATES.add(new TaxRate(new BigDecimal("960000"), new BigDecimal("0.35"), new BigDecimal("85920")));
        ANNUAL_TAX_RATES.add(new TaxRate(null, new BigDecimal("0.45"), new BigDecimal("181920"))); // 超过960000元的部分
    }

    /**
     * 计算当月应预扣税额
     *
     * @param cumulativeIncome    累计收入（税前）
     * @param taxMonth            当前月份（1-12）
     * @param cumulativePrepaidTax 累计已预缴税额
     * @return 当月应预扣税额（BigDecimal，保留2位小数）
     */
    public static BigDecimal calculateMonthlyWithholdingTax(
        BigDecimal cumulativeIncome,
        int taxMonth,
        BigDecimal cumulativePrepaidTax
    ) {
        // 1. 参数校验
        validateParams(cumulativeIncome, taxMonth, cumulativePrepaidTax);

        // 2. 计算累计减除费用：5000 * n（n为月份）
        BigDecimal cumulativeDeduction = MONTHLY_DEDUCTION.multiply(new BigDecimal(taxMonth));

        // 3. 计算应纳税所得额：累计收入 × (1 - 20%) - 累计减除费用
        BigDecimal taxableIncome = cumulativeIncome
            .multiply(BigDecimal.ONE.subtract(INCOME_DEDUCTION_RATIO))
            .subtract(cumulativeDeduction)
            .setScale(2, RoundingMode.HALF_UP); // 保留2位小数

        // 4. 如果应纳税所得额≤0，当月无需缴税
        if (taxableIncome.compareTo(BigDecimal.ZERO) <= 0) {
            return BigDecimal.ZERO;
        }

        // 5. 匹配税率和速算扣除数
        TaxRate matchedRate = matchTaxRate(taxableIncome);

        // 6. 计算当月应预扣税额：应纳税所得额 × 税率 - 速算扣除数 - 已预缴税额
        BigDecimal withholdingTax = taxableIncome
            .multiply(matchedRate.rate)
            .subtract(matchedRate.quickDeduction)
            .subtract(cumulativePrepaidTax)
            .setScale(2, RoundingMode.HALF_UP); // 保留2位小数

        // 7. 确保税额≥0（避免出现负数）
        return withholdingTax.max(BigDecimal.ZERO);
    }

    /**
     * 匹配税率（根据应纳税所得额找到对应的税率和速算扣除数）
     *
     * @param taxableIncome 应纳税所得额
     * @return 匹配的税率信息（TaxRate对象）
     */
    private static TaxRate matchTaxRate(BigDecimal taxableIncome) {
        for (TaxRate rate : ANNUAL_TAX_RATES) {
            if (rate.upperLimit == null) { // 最后一级（超过960000元的部分）
                return rate;
            }
            if (taxableIncome.compareTo(rate.upperLimit) <= 0) {
                return rate;
            }
        }
        return ANNUAL_TAX_RATES.get(ANNUAL_TAX_RATES.size() - 1); // 兜底（理论上不会触发）
    }

    /**
     * 参数校验
     *
     * @param cumulativeIncome    累计收入
     * @param taxMonth            当前月份
     * @param cumulativePrepaidTax 累计已预缴税额
     */
    private static void validateParams(
        BigDecimal cumulativeIncome,
        int taxMonth,
        BigDecimal cumulativePrepaidTax
    ) {
        if (cumulativeIncome == null || cumulativeIncome.compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("累计收入不能为负数或空！");
        }
        if (taxMonth < 1 || taxMonth > 12) {
            throw new IllegalArgumentException("月份必须在1-12之间！");
        }
        if (cumulativePrepaidTax == null || cumulativePrepaidTax.compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("累计已预缴税额不能为负数或空！");
        }
    }

    /**
     * 税率实体类（内部静态类）
     */
    private static class TaxRate {
        private final BigDecimal upperLimit; // 级距上限（最后一级为null）
        private final BigDecimal rate;       // 税率
        private final BigDecimal quickDeduction; // 速算扣除数

        public TaxRate(BigDecimal upperLimit, BigDecimal rate, BigDecimal quickDeduction) {
            this.upperLimit = upperLimit;
            this.rate = rate;
            this.quickDeduction = quickDeduction;
        }
    }

    // 示例：测试工具类
    public static void main(String[] args) {
        // 测试用例1：累计收入 100000元，第7个月，已预缴税额 1500元
        BigDecimal cumulativeIncome = new BigDecimal("100000");
        int taxMonth = 7;
        BigDecimal cumulativePrepaidTax = new BigDecimal("1500");

        BigDecimal tax = calculateMonthlyWithholdingTax(cumulativeIncome, taxMonth, cumulativePrepaidTax);
        System.out.println("测试用例1：");
        System.out.println("累计收入：" + cumulativeIncome + "元，月份：" + taxMonth + "，已预缴税额：" + cumulativePrepaidTax + "元");
        System.out.println("当月应预扣税额：" + tax + "元\n");

        // 测试用例2：累计收入 400000元，第10个月，已预缴税额 30000元
        cumulativeIncome = new BigDecimal("400000");
        taxMonth = 10;
        cumulativePrepaidTax = new BigDecimal("30000");

        tax = calculateMonthlyWithholdingTax(cumulativeIncome, taxMonth, cumulativePrepaidTax);
        System.out.println("测试用例2：");
        System.out.println("累计收入：" + cumulativeIncome + "元，月份：" + taxMonth + "，已预缴税额：" + cumulativePrepaidTax + "元");
        System.out.println("当月应预扣税额：" + tax + "元");
    }
}
