package com.sundot.airport.common.statistics;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 多模型指标计算器
 * 支持多种指标类型的计算，包括环比和同比
 */
@Component
public class MultiModelIndicatorCalculator {

    @Autowired
    private TimeDimensionProcessor timeDimensionProcessor;

    /**
     * 计算指标，支持环比和同比
     *
     * @param calculator 指标计算器
     * @param params     计算参数
     * @return 指标计算结果
     */
    public IndicatorCalculationResult calculateWithRatio(IndicatorCalculator<?> calculator,
                                                         IndicatorCalculationParams params) {
        // 首先计算当前指标值
        Object currentValue = calculator.calculate(params);
        BigDecimal currentDecimalValue = convertToBigDecimal(currentValue);

        IndicatorCalculationResult result = new IndicatorCalculationResult();
        result.setIndicatorType(calculator.getIndicatorType());
        result.setIndicatorName(calculator.getIndicatorName());
        result.setValue(currentDecimalValue);

        // 设置时间维度信息
        StringBuilder timeInfo = new StringBuilder();
        if (params.getYear() != null) {
            timeInfo.append(params.getYear()).append("年");
            if (params.getQuarter() != null) {
                timeInfo.append(params.getQuarter()).append("季度");
            } else if (params.getMonth() != null) {
                timeInfo.append(params.getMonth()).append("月");
            }
        } else if (params.getStartTime() != null && params.getEndTime() != null) {
            timeInfo.append(params.getStartTime()).append("至").append(params.getEndTime());
        }
        result.setTimeDimensionInfo(timeInfo.toString());

        // 根据时间维度决定计算哪些比率
        boolean needChainRatio = params.getChainRatio() != null && params.getChainRatio();
        boolean needYearOnYear = params.getYearOnYear() != null && params.getYearOnYear();

        // 当选择年度时，只计算同比
        if (params.getYear() != null && params.getQuarter() == null && params.getMonth() == null) {
            needChainRatio = false;
        }

        // 计算环比
        if (needChainRatio) {
            try {
                // 计算环比时间范围
                TimeDimensionParams chainRatioParams = timeDimensionProcessor.calculateChainRatioTimeRange(
                        params, params.getComparePeriods());

                // 创建环比参数
                IndicatorCalculationParams chainRatioCalcParams = new IndicatorCalculationParams();
                chainRatioCalcParams.setStartTime(chainRatioParams.getStartTime());
                chainRatioCalcParams.setEndTime(chainRatioParams.getEndTime());
                chainRatioCalcParams.setYear(chainRatioParams.getYear());
                chainRatioCalcParams.setQuarter(chainRatioParams.getQuarter());
                chainRatioCalcParams.setMonth(chainRatioParams.getMonth());
                chainRatioCalcParams.setIndicatorType(params.getIndicatorType());
                chainRatioCalcParams.setModuleName(params.getModuleName());
                chainRatioCalcParams.setDeptId(params.getDeptId());
                chainRatioCalcParams.setUserId(params.getUserId());
                chainRatioCalcParams.setSpecificParams(params.getSpecificParams());
                chainRatioCalcParams.setContextParams(params.getContextParams());

                // 计算环比基准值
                Object chainRatioValue = calculator.calculate(chainRatioCalcParams);
                BigDecimal chainRatioDecimalValue = convertToBigDecimal(chainRatioValue);

                // 计算环比增长率
                String chainRatioGrowth = calculateRatioGrowth(currentDecimalValue, chainRatioDecimalValue);
                result.setChainRatioValue(chainRatioGrowth);
                result.setBaselineValue(chainRatioDecimalValue);
                Map<String, Object> extraInfo = new HashMap<>();
                extraInfo.put("chainRatio", chainRatioParams);
                result.setExtraInfo(extraInfo);
            } catch (Exception e) {
                result.setErrorMessage("环比计算失败: " + e.getMessage());
            }
        }

        // 计算同比
        if (needYearOnYear) {
            try {
                // 计算同比时间范围
                TimeDimensionParams yearOnYearParams = timeDimensionProcessor.calculateYearOnYearTimeRange(params);

                // 创建同比参数
                IndicatorCalculationParams yearOnYearCalcParams = new IndicatorCalculationParams();
                yearOnYearCalcParams.setStartTime(yearOnYearParams.getStartTime());
                yearOnYearCalcParams.setEndTime(yearOnYearParams.getEndTime());
                yearOnYearCalcParams.setYear(yearOnYearParams.getYear());
                yearOnYearCalcParams.setQuarter(yearOnYearParams.getQuarter());
                yearOnYearCalcParams.setMonth(yearOnYearParams.getMonth());
                yearOnYearCalcParams.setIndicatorType(params.getIndicatorType());
                yearOnYearCalcParams.setModuleName(params.getModuleName());
                yearOnYearCalcParams.setDeptId(params.getDeptId());
                yearOnYearCalcParams.setUserId(params.getUserId());
                yearOnYearCalcParams.setSpecificParams(params.getSpecificParams());
                yearOnYearCalcParams.setContextParams(params.getContextParams());

                // 计算同比基准值
                Object yearOnYearValue = calculator.calculate(yearOnYearCalcParams);
                BigDecimal yearOnYearDecimalValue = convertToBigDecimal(yearOnYearValue);

                // 计算同比增长率
                String yearOnYearGrowth = calculateRatioGrowth(currentDecimalValue, yearOnYearDecimalValue);
                result.setYearOnYearValue(yearOnYearGrowth);
                Map<String, Object> extraInfo = new HashMap<>();
                extraInfo.put("yearOnYear", yearOnYearParams);
                result.setExtraInfo(extraInfo);
            } catch (Exception e) {
                result.setErrorMessage("同比计算失败: " + e.getMessage());
            }
        }

        result.setStatus("SUCCESS");
        return result;
    }

    /**
     * 计算比率增长
     *
     * @param current  当前值
     * @param baseline 基准值
     * @return 增长率
     */
    private String calculateRatioGrowth(BigDecimal current, BigDecimal baseline) {
        if (baseline == null || baseline.compareTo(BigDecimal.ZERO) == 0) {
            if (current != null && current.compareTo(BigDecimal.ZERO) > 0) {
                return "--";
            }
            return BigDecimal.ZERO.toString();
        }

        if (current == null) {
            current = BigDecimal.ZERO;
        }

        // 计算增长率: (当前值 - 基准值) / 基准值 * 100%
        return current.subtract(baseline)
                .divide(baseline, 4, BigDecimal.ROUND_HALF_UP)
                .multiply(new BigDecimal("100"))
                .setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 将对象转换为BigDecimal
     *
     * @param obj 待转换对象
     * @return BigDecimal值
     */
    private BigDecimal convertToBigDecimal(Object obj) {
        if (obj == null) {
            return BigDecimal.ZERO;
        }

        if (obj instanceof BigDecimal) {
            return (BigDecimal) obj;
        } else if (obj instanceof Number) {
            return new BigDecimal(obj.toString());
        } else if (obj instanceof String) {
            try {
                return new BigDecimal((String) obj);
            } catch (NumberFormatException e) {
                return BigDecimal.ZERO;
            }
        } else {
            return BigDecimal.ZERO;
        }
    }
}