package com.ruoyi.oa.service.impl;

import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.oa.domain.vo.*;
import com.ruoyi.oa.domain.vo.dashboard.*;
import com.ruoyi.oa.mapper.SalaryDashboardMapper;
import com.ruoyi.oa.service.ISalaryDashboardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service
public class SalaryDashboardServiceImpl implements ISalaryDashboardService {

    @Autowired
    private SalaryDashboardMapper dashboardMapper;

    @Override
    public SalaryDashboardVo getDashboardData(Long payYear, Long payMonth) {
        SalaryDashboardVo dashboardVo = new SalaryDashboardVo();

        // 1. 获取卡片数据
        dashboardVo.setCardData(getCardData(payYear, payMonth));

        // 2. 获取图表数据
        dashboardVo.setChartData(getChartData(payYear, payMonth));

        // 3. 获取部门统计表格数据
        List<DepartmentStatVo> deptStats = dashboardMapper.queryDepartmentStats(payYear, payMonth);
        TableDataInfo<DepartmentStatVo> tableData = new TableDataInfo<>(deptStats, deptStats.size());
        dashboardVo.setDepartmentStats(tableData);
        return dashboardVo;
    }

    private CardDataVo getCardData(Long payYear, Long payMonth) {
        CardDataVo cardData = new CardDataVo();

        // 初始化所有数值为0，避免NPE
        cardData.setTotalSalaryExpenditure(BigDecimal.ZERO);
        cardData.setLastMonthTotalSalaryExpenditureRate(BigDecimal.ZERO);
        cardData.setAvgDepartmentExpenditure(BigDecimal.ZERO);
        cardData.setLastMonthAvgDepartmentExpenditureRate(BigDecimal.ZERO);
        cardData.setAvgPersonSalary(BigDecimal.ZERO);
        cardData.setLastMonthAvgPersonSalaryRate(BigDecimal.ZERO);
        cardData.setYearOnYearGrowthRate(BigDecimal.ZERO);

        // 获取当月数据
        CardMetricsVo currentMonthMetrics = dashboardMapper.queryCardMetrics(payYear, payMonth);
        if (currentMonthMetrics == null) {
            return cardData; // 如果当月没有数据，直接返回零值
        }

        // 设置当月总支出
        cardData.setTotalSalaryExpenditure(
                currentMonthMetrics.getTotalSalaryExpenditure() != null ?
                        currentMonthMetrics.getTotalSalaryExpenditure() : BigDecimal.ZERO
        );

        // 获取上月数据 (处理1月的情况)
        Long lastMonth = payMonth == 1 ? 12 : payMonth - 1;
        Long lastYear = payMonth == 1 ? payYear - 1 : payYear;
        CardMetricsVo lastMonthMetrics = dashboardMapper.queryCardMetrics(lastYear, lastMonth);

        // 计算较上月增长率
        if (lastMonthMetrics != null &&
                lastMonthMetrics.getTotalSalaryExpenditure() != null &&
                lastMonthMetrics.getTotalSalaryExpenditure().compareTo(BigDecimal.ZERO) != 0) {
            try {
                BigDecimal monthGrowth = currentMonthMetrics.getTotalSalaryExpenditure()
                        .subtract(lastMonthMetrics.getTotalSalaryExpenditure())
                        .divide(lastMonthMetrics.getTotalSalaryExpenditure(), 4, RoundingMode.HALF_UP)
                        .multiply(new BigDecimal("100"));
                cardData.setLastMonthTotalSalaryExpenditureRate(monthGrowth);
            } catch (Exception e) {
                cardData.setLastMonthTotalSalaryExpenditureRate(BigDecimal.ZERO);
            }
        }

        // 计算部门平均支出
        if (currentMonthMetrics.getDepartmentCount() != null &&
                currentMonthMetrics.getDepartmentCount() > 0 &&
                currentMonthMetrics.getTotalCompanyExpenditure() != null) {
            try {
                BigDecimal avgDeptExpenditure = currentMonthMetrics.getTotalCompanyExpenditure()
                        .divide(new BigDecimal(currentMonthMetrics.getDepartmentCount()), 2, RoundingMode.HALF_UP);
                cardData.setAvgDepartmentExpenditure(avgDeptExpenditure);
            } catch (Exception e) {
                cardData.setAvgDepartmentExpenditure(BigDecimal.ZERO);
            }
        }

        // 计算人均实发工资
        if (currentMonthMetrics.getEmployeeCount() != null &&
                currentMonthMetrics.getEmployeeCount() > 0 &&
                currentMonthMetrics.getTotalSalaryExpenditure() != null) {
            try {
                BigDecimal avgPersonSalary = currentMonthMetrics.getTotalSalaryExpenditure()
                        .divide(new BigDecimal(currentMonthMetrics.getEmployeeCount()), 2, RoundingMode.HALF_UP);
                cardData.setAvgPersonSalary(avgPersonSalary);
            } catch (Exception e) {
                cardData.setAvgPersonSalary(BigDecimal.ZERO);
            }
        }

        // 获取去年同期数据并计算同比增长率
        CardMetricsVo lastYearMetrics = dashboardMapper.queryCardMetrics(payYear - 1, payMonth);
        if (lastYearMetrics != null &&
                lastYearMetrics.getEmployeeCount() != null &&
                lastYearMetrics.getEmployeeCount() > 0 &&
                lastYearMetrics.getTotalSalaryExpenditure() != null) {
            try {
                BigDecimal lastYearAvgSalary = lastYearMetrics.getTotalSalaryExpenditure()
                        .divide(new BigDecimal(lastYearMetrics.getEmployeeCount()), 2, RoundingMode.HALF_UP);
                if (lastYearAvgSalary.compareTo(BigDecimal.ZERO) != 0 &&
                        cardData.getAvgPersonSalary() != null) {
                    BigDecimal yearGrowth = cardData.getAvgPersonSalary()
                            .subtract(lastYearAvgSalary)
                            .divide(lastYearAvgSalary, 4, RoundingMode.HALF_UP)
                            .multiply(new BigDecimal("100"));
                    cardData.setYearOnYearGrowthRate(yearGrowth);
                }
            } catch (Exception e) {
                cardData.setYearOnYearGrowthRate(BigDecimal.ZERO);
            }
        }

        return cardData;
    }

    private ChartDataVo getChartData(Long payYear, Long payMonth) {
        ChartDataVo chartData = new ChartDataVo();

        // 1. 获取柱状图数据 (年度每月总支出)
        List<MonthlyExpenditureVo> monthlyExpenditures =
                dashboardMapper.queryMonthlyExpenditures(payYear);
        chartData.setMonthlyExpenditures(monthlyExpenditures != null ?
                monthlyExpenditures : new ArrayList<>());

        // 2. 获取饼图数据 (薪资构成)
        List<SalaryComponentVo> salaryComponents =
                dashboardMapper.querySalaryComponents(payYear, payMonth);
        chartData.setSalaryComponents(salaryComponents != null ?
                salaryComponents : new ArrayList<>());

        // 3. 获取折线图数据 (总支出 vs 平均工资)
        List<LineChartPointVo> lineChartData =
                dashboardMapper.queryLineChartData(payYear);
        chartData.setLineChartData(new LineChartVo(
                lineChartData != null ? lineChartData : new ArrayList<>()
        ));

        return chartData;
    }

    @Override
    public NewSalaryDashboardVo getNewDashboardData(String salaryPeriod) {
        NewSalaryDashboardVo dashboardVo = new NewSalaryDashboardVo();

        // 1. 获取卡片数据
        dashboardVo.setCardData(getNewCardData(salaryPeriod));

        // 2. 获取图表数据
        String[] periodParts = salaryPeriod.split("-");
        Integer year = Integer.valueOf(periodParts[0]);
        dashboardVo.setChartData(getNewChartData(salaryPeriod, year));

        // 3. 获取单位统计表格数据
        List<UnitStatVo> unitStats = dashboardMapper.queryUnitStats(salaryPeriod);
        TableDataInfo<UnitStatVo> unitTableData = new TableDataInfo<>(unitStats, unitStats.size());
        dashboardVo.setUnitStats(unitTableData);

        // 4. 获取部门统计表格数据
        List<DeptSalaryStatVo> deptStats = dashboardMapper.queryDeptSalaryStats(salaryPeriod);
        TableDataInfo<DeptSalaryStatVo> deptTableData = new TableDataInfo<>(deptStats, deptStats.size());
        dashboardVo.setDeptStats(deptTableData);

        return dashboardVo;
    }



    /**
     * 获取新卡片数据
     */
    private NewCardDataVo getNewCardData(String salaryPeriod) {
        NewCardDataVo cardData = new NewCardDataVo();

        // 初始化所有数值为0，避免NPE
        cardData.setTotalNetSalary(BigDecimal.ZERO);
        cardData.setLastMonthNetSalaryRate(BigDecimal.ZERO);
        cardData.setTotalGrossSalary(BigDecimal.ZERO);
        cardData.setLastMonthGrossSalaryRate(BigDecimal.ZERO);
        cardData.setTotalUnitExpense(BigDecimal.ZERO);
        cardData.setLastMonthUnitExpenseRate(BigDecimal.ZERO);
        cardData.setAvgNetSalary(BigDecimal.ZERO);
        cardData.setLastMonthAvgNetSalaryRate(BigDecimal.ZERO);
        cardData.setYearOnYearGrowthRate(BigDecimal.ZERO);
        cardData.setTotalEmployeeCount(0);
        cardData.setUnitCount(0);

        // 获取当月数据
        NewCardMetricsVo currentMonthMetrics = dashboardMapper.queryNewCardMetrics(salaryPeriod);
        if (currentMonthMetrics == null) {
            return cardData; // 如果当月没有数据，直接返回零值
        }

        // 设置当月数据
        cardData.setTotalNetSalary(currentMonthMetrics.getTotalNetSalary() != null ?
                currentMonthMetrics.getTotalNetSalary() : BigDecimal.ZERO);
        cardData.setTotalGrossSalary(currentMonthMetrics.getTotalGrossSalary() != null ?
                currentMonthMetrics.getTotalGrossSalary() : BigDecimal.ZERO);
        cardData.setTotalUnitExpense(currentMonthMetrics.getTotalUnitExpense() != null ?
                currentMonthMetrics.getTotalUnitExpense() : BigDecimal.ZERO);
        cardData.setTotalEmployeeCount(currentMonthMetrics.getEmployeeCount() != null ?
                currentMonthMetrics.getEmployeeCount() : 0);
        cardData.setUnitCount(currentMonthMetrics.getUnitCount() != null ?
                currentMonthMetrics.getUnitCount() : 0);

        // 计算人均实发工资
        if (currentMonthMetrics.getEmployeeCount() != null &&
                currentMonthMetrics.getEmployeeCount() > 0 &&
                currentMonthMetrics.getTotalNetSalary() != null) {
            try {
                BigDecimal avgNetSalary = currentMonthMetrics.getTotalNetSalary()
                        .divide(new BigDecimal(currentMonthMetrics.getEmployeeCount()), 2, RoundingMode.HALF_UP);
                cardData.setAvgNetSalary(avgNetSalary);
            } catch (Exception e) {
                cardData.setAvgNetSalary(BigDecimal.ZERO);
            }
        }

        // 计算上月对比数据
        String lastMonthPeriod = getLastMonthPeriod(salaryPeriod);
        NewCardMetricsVo lastMonthMetrics = dashboardMapper.queryNewCardMetrics(lastMonthPeriod);

        if (lastMonthMetrics != null) {
            // 计算实发工资增长率
            if (lastMonthMetrics.getTotalNetSalary() != null &&
                    lastMonthMetrics.getTotalNetSalary().compareTo(BigDecimal.ZERO) != 0) {
                try {
                    BigDecimal netSalaryGrowth = currentMonthMetrics.getTotalNetSalary()
                            .subtract(lastMonthMetrics.getTotalNetSalary())
                            .divide(lastMonthMetrics.getTotalNetSalary(), 4, RoundingMode.HALF_UP)
                            .multiply(new BigDecimal("100"));
                    cardData.setLastMonthNetSalaryRate(netSalaryGrowth);
                } catch (Exception e) {
                    cardData.setLastMonthNetSalaryRate(BigDecimal.ZERO);
                }
            }

            // 计算应发工资增长率
            if (lastMonthMetrics.getTotalGrossSalary() != null &&
                    lastMonthMetrics.getTotalGrossSalary().compareTo(BigDecimal.ZERO) != 0) {
                try {
                    BigDecimal grossSalaryGrowth = currentMonthMetrics.getTotalGrossSalary()
                            .subtract(lastMonthMetrics.getTotalGrossSalary())
                            .divide(lastMonthMetrics.getTotalGrossSalary(), 4, RoundingMode.HALF_UP)
                            .multiply(new BigDecimal("100"));
                    cardData.setLastMonthGrossSalaryRate(grossSalaryGrowth);
                } catch (Exception e) {
                    cardData.setLastMonthGrossSalaryRate(BigDecimal.ZERO);
                }
            }

            // 计算单位总支出增长率
            if (lastMonthMetrics.getTotalUnitExpense() != null &&
                    lastMonthMetrics.getTotalUnitExpense().compareTo(BigDecimal.ZERO) != 0) {
                try {
                    BigDecimal unitExpenseGrowth = currentMonthMetrics.getTotalUnitExpense()
                            .subtract(lastMonthMetrics.getTotalUnitExpense())
                            .divide(lastMonthMetrics.getTotalUnitExpense(), 4, RoundingMode.HALF_UP)
                            .multiply(new BigDecimal("100"));
                    cardData.setLastMonthUnitExpenseRate(unitExpenseGrowth);
                } catch (Exception e) {
                    cardData.setLastMonthUnitExpenseRate(BigDecimal.ZERO);
                }
            }
        }

        // 计算同比增长率（与去年同期相比）
        String lastYearPeriod = getLastYearPeriod(salaryPeriod);
        NewCardMetricsVo lastYearMetrics = dashboardMapper.queryNewCardMetrics(lastYearPeriod);

        if (lastYearMetrics != null &&
                lastYearMetrics.getEmployeeCount() != null &&
                lastYearMetrics.getEmployeeCount() > 0 &&
                lastYearMetrics.getTotalNetSalary() != null) {
            try {
                BigDecimal lastYearAvgSalary = lastYearMetrics.getTotalNetSalary()
                        .divide(new BigDecimal(lastYearMetrics.getEmployeeCount()), 2, RoundingMode.HALF_UP);
                if (lastYearAvgSalary.compareTo(BigDecimal.ZERO) != 0 &&
                        cardData.getAvgNetSalary() != null) {
                    BigDecimal yearGrowth = cardData.getAvgNetSalary()
                            .subtract(lastYearAvgSalary)
                            .divide(lastYearAvgSalary, 4, RoundingMode.HALF_UP)
                            .multiply(new BigDecimal("100"));
                    cardData.setYearOnYearGrowthRate(yearGrowth);
                }
            } catch (Exception e) {
                cardData.setYearOnYearGrowthRate(BigDecimal.ZERO);
            }
        }

        return cardData;
    }

    /**
     * 获取新图表数据
     */
    private NewChartDataVo getNewChartData(String salaryPeriod, Integer year) {
        NewChartDataVo chartData = new NewChartDataVo();

        // 1. 获取月度支出数据
        List<MonthlyExpenseVo> monthlyExpenses = dashboardMapper.queryMonthlyExpenses(year);
        chartData.setMonthlyExpenses(monthlyExpenses != null ? monthlyExpenses : new ArrayList<>());

        // 2. 获取工资构成数据
        List<SalaryStructureVo> salaryStructures = dashboardMapper.querySalaryStructures(salaryPeriod);
        chartData.setSalaryStructures(salaryStructures != null ? salaryStructures : new ArrayList<>());

        // 3. 获取趋势数据
        List<SalaryTrendPointVo> trendData = dashboardMapper.querySalaryTrendData(year);
        chartData.setTrendData(new SalaryTrendVo(trendData != null ? trendData : new ArrayList<>()));

        // 4. 获取社保公积金统计数据
        List<InsuranceStatVo> insuranceStats = dashboardMapper.queryInsuranceStats(salaryPeriod);
        chartData.setInsuranceStats(insuranceStats != null ? insuranceStats : new ArrayList<>());

        return chartData;
    }

    /**
     * 获取上月期间
     */
    private String getLastMonthPeriod(String salaryPeriod) {
        String[] parts = salaryPeriod.split("-");
        int year = Integer.parseInt(parts[0]);
        int month = Integer.parseInt(parts[1]);

        if (month == 1) {
            year--;
            month = 12;
        } else {
            month--;
        }

        return String.format("%d-%02d", year, month);
    }

    /**
     * 获取去年同期
     */
    private String getLastYearPeriod(String salaryPeriod) {
        String[] parts = salaryPeriod.split("-");
        int year = Integer.parseInt(parts[0]) - 1;
        int month = Integer.parseInt(parts[1]);

        return String.format("%d-%02d", year, month);
    }
}