package com.sundot.airport.web.controller.personnel;

import com.sundot.airport.common.core.controller.BaseController;
import com.sundot.airport.common.core.domain.AjaxResult;
import com.sundot.airport.common.core.domain.entity.SysDept;
import com.sundot.airport.common.core.domain.entity.SysUser;
import com.sundot.airport.personnel.dto.AssessmentSummaryDto;
import com.sundot.airport.personnel.dto.FunctionalDeptSummaryDto;
import com.sundot.airport.personnel.dto.FunctionalDeptPersonnelDistributionDto;
import com.sundot.airport.personnel.dto.FunctionalDeptDistributionPieDto;
import com.sundot.airport.personnel.dto.AssessmentTeamActualImprovementDistributionDto;
import com.sundot.airport.personnel.dto.AssessmentTeamActualIncompetentDistributionDto;
import com.sundot.airport.personnel.dto.DeptActualImprovementDistributionDto;
import com.sundot.airport.personnel.dto.DeptActualIncompetentDistributionDto;
import com.sundot.airport.personnel.dto.DeptAssessmentTeamStatisticsDto;
import com.sundot.airport.personnel.dto.DeptParticipationDto;
import com.sundot.airport.personnel.dto.ScoreDistributionDto;
import com.sundot.airport.personnel.dto.ScoreRangeDistributionDto;
import com.sundot.airport.personnel.domain.PersonnelNonCadreMonthlyAssessment;
import com.sundot.airport.personnel.service.IPersonnelNonCadreMonthlyAssessmentService;
import com.sundot.airport.system.service.ISysDeptService;
import com.sundot.airport.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 非干部月度考核分数汇总Controller
 *
 * @author wangxx
 * @date 2026-05-09
 */
@RestController
@RequestMapping("/personnel/non-cadre-assessment/score-summary")
public class PersonnelNonCadreMonthlyAssessmentScoreSummaryController extends BaseController {

    @Autowired
    private IPersonnelNonCadreMonthlyAssessmentService personnelNonCadreMonthlyAssessmentService;

    @Autowired
    private ISysDeptService sysDeptService;

    @Autowired
    private ISysUserService sysUserService;

    // 常量定义，避免重复创建
    private static final BigDecimal SCORE_90 = new BigDecimal("90");
    private static final BigDecimal SCORE_85 = new BigDecimal("85");
    private static final BigDecimal SCORE_80 = new BigDecimal("80");
    private static final BigDecimal SCORE_75 = new BigDecimal("75");
    private static final BigDecimal SCORE_70 = new BigDecimal("70");
    private static final BigDecimal HUNDRED = new BigDecimal("100");
    private static final String EXEMPTION_YES = "是";
    private static final String RESULT_IMPROVEMENT = "待改进";
    private static final String RESULT_INCOMPETENT = "不称职";

    /**
     * 分值汇总分布 - 按照总分字段统计各分段人数
     *
     * @param assessmentMonth 考核月份（格式:YYYYMM）
     * @return 各分数段人数统计
     */
    @PreAuthorize("@ss.hasPermi('personnel:assessment:query')")
    @GetMapping("/score-distribution")
    public AjaxResult getScoreDistribution(@RequestParam String assessmentMonth) {
        try {
            List<PersonnelNonCadreMonthlyAssessment> list = queryByMonth(assessmentMonth);

            if (list == null || list.isEmpty()) {
                return success(createEmptyScoreDistribution());
            }

            // 统计各分数段人数
            int above90 = 0;
            int range85To89 = 0;
            int range80To84 = 0;
            int range70To79 = 0;
            int below69 = 0;

            for (PersonnelNonCadreMonthlyAssessment item : list) {
                BigDecimal totalScore = item.getTotalScore();
                if (totalScore == null) {
                    continue;
                }

                if (totalScore.compareTo(SCORE_90) >= 0) {
                    above90++;
                } else if (totalScore.compareTo(SCORE_85) >= 0) {
                    range85To89++;
                } else if (totalScore.compareTo(SCORE_80) >= 0) {
                    range80To84++;
                } else if (totalScore.compareTo(SCORE_70) >= 0) {
                    range70To79++;
                } else {
                    below69++;
                }
            }

            // 构建返回结果
            List<ScoreDistributionDto> result = new ArrayList<>();
            int totalCount = above90 + range85To89 + range80To84 + range70To79 + below69;

            result.add(createScoreDistributionDto("90分以上", above90));
            result.add(createScoreDistributionDto("85-89分", range85To89));
            result.add(createScoreDistributionDto("80-84分", range80To84));
            result.add(createScoreDistributionDto("70-79分", range70To79));
            result.add(createScoreDistributionDto("69分及以下", below69));
            result.add(createScoreDistributionDto("总计", totalCount));

            return success(result);
        } catch (Exception e) {
            logger.error("分值汇总分布统计异常", e);
            return error("统计失败：" + e.getMessage());
        }
    }

    /**
     * 创建分数分布DTO
     */
    private ScoreDistributionDto createScoreDistributionDto(String range, Integer count) {
        ScoreDistributionDto dto = new ScoreDistributionDto();
        dto.setScoreRange(range);
        dto.setCount(count);
        return dto;
    }

    /**
     * 各部门参与人数占比
     *
     * @param assessmentMonth 考核月份（格式:YYYYMM）
     * @return 各大队参与人数及占比
     */
    @PreAuthorize("@ss.hasPermi('personnel:assessment:query')")
    @GetMapping("/dept-participation")
    public AjaxResult getDeptParticipation(@RequestParam String assessmentMonth) {
        try {
            List<PersonnelNonCadreMonthlyAssessment> list = queryByMonth(assessmentMonth);

            if (list == null || list.isEmpty()) {
                return success(Collections.emptyList());
            }

            // 获取所有部门信息
            Map<Long, SysDept> deptMap = getDeptMap();
            
            // 构建大队到其所有子部门ID的映射
            Map<Long, Set<Long>> brigadeSubDeptsMap = buildBrigadeSubDeptsMap(deptMap);

            // 批量查询用户部门映射
            Set<Long> userIds = list.stream()
                    .map(PersonnelNonCadreMonthlyAssessment::getUserId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            Map<Long, Long> userDeptIdMap = buildUserDeptIdMap(userIds);

            // 按大队统计人数
            Map<Long, Integer> brigadeCountMap = new HashMap<>();
            int totalCount = list.size();

            for (PersonnelNonCadreMonthlyAssessment item : list) {
                Long userDeptId = userDeptIdMap.get(item.getUserId());
                if (userDeptId != null) {
                    // 查找该用户所属的大队
                    Long brigadeId = findUserBrigade(userDeptId, brigadeSubDeptsMap);
                    if (brigadeId != null) {
                        brigadeCountMap.merge(brigadeId, 1, Integer::sum);
                    }
                }
            }

            // 构建返回结果
            List<DeptParticipationDto> result = new ArrayList<>();
            for (Map.Entry<Long, Integer> entry : brigadeCountMap.entrySet()) {
                Long brigadeId = entry.getKey();
                Integer count = entry.getValue();

                DeptParticipationDto dto = new DeptParticipationDto();
                dto.setDeptId(brigadeId);

                SysDept brigade = deptMap.get(brigadeId);
                if (brigade != null) {
                    dto.setDeptName(brigade.getDeptName());
                    dto.setDeptType(brigade.getDeptType());
                    dto.setDeptTypeDesc(brigade.getDeptTypeDesc());
                }

                dto.setCount(count);
                // 计算占比
                if (totalCount > 0) {
                    BigDecimal percentage = new BigDecimal(count)
                            .divide(new BigDecimal(totalCount), 4, BigDecimal.ROUND_HALF_UP)
                            .multiply(HUNDRED);
                    dto.setPercentage(percentage.setScale(2, BigDecimal.ROUND_HALF_UP));
                } else {
                    dto.setPercentage(BigDecimal.ZERO);
                }

                result.add(dto);
            }

            // 按人数降序排序
            result.sort((a, b) -> b.getCount().compareTo(a.getCount()));

            return success(result);
        } catch (Exception e) {
            logger.error("各部门参与人数占比统计异常", e);
            return error("统计失败：" + e.getMessage());
        }
    }

    /**
     * 各部门分值分布（按大队级别统计）
     * @param assessmentMonth 考核月份（格式:YYYYMM）
     * @return 各分数段的大队人数分布
     */
    @PreAuthorize("@ss.hasPermi('personnel:assessment:query')")
    @GetMapping("/dept-score-distribution")
    public AjaxResult getDeptScoreDistribution(@RequestParam String assessmentMonth) {
        try {
            List<PersonnelNonCadreMonthlyAssessment> list = queryByMonth(assessmentMonth);

            if (list == null || list.isEmpty()) {
                return success(createEmptyScoreRangeDistribution());
            }

            // 获取所有部门信息
            Map<Long, SysDept> deptMap = getDeptMap();
            
            // 构建大队到其所有子部门ID的映射
            Map<Long, Set<Long>> brigadeSubDeptsMap = buildBrigadeSubDeptsMap(deptMap);

            // 批量查询用户部门映射
            Set<Long> userIds = list.stream()
                    .map(PersonnelNonCadreMonthlyAssessment::getUserId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            Map<Long, Long> userDeptIdMap = buildUserDeptIdMap(userIds);

            // 定义6个分数段
            String[] rangeKeys = {"below70", "70-75", "75-80", "80-85", "85-90", "above90"};
            String[] rangeLabels = {"低于70", "[70-75)", "[75-80)", "[80-85)", "[85-90)", "90以上"};

            Map<String, Map<Long, Integer>> rangeBrigadeCountMap = new LinkedHashMap<>();
            for (String rangeKey : rangeKeys) {
                rangeBrigadeCountMap.put(rangeKey, new HashMap<>());
            }

            // 统计每个分数段下各大队的人数
            for (PersonnelNonCadreMonthlyAssessment item : list) {
                Long userDeptId = userDeptIdMap.get(item.getUserId());
                if (userDeptId == null) {
                    continue;
                }

                BigDecimal totalScore = item.getTotalScore();
                if (totalScore == null) {
                    continue;
                }

                // 查找该用户所属的大队
                Long brigadeId = findUserBrigade(userDeptId, brigadeSubDeptsMap);
                if (brigadeId == null) {
                    continue;
                }

                // 确定分数段
                String rangeKey = determineScoreRange(totalScore);

                // 累加该大队在该分数段的人数
                Map<Long, Integer> brigadeCountMap = rangeBrigadeCountMap.get(rangeKey);
                brigadeCountMap.merge(brigadeId, 1, Integer::sum);
            }

            // 构建返回结果
            List<ScoreRangeDistributionDto> result = new ArrayList<>();
            for (int i = 0; i < rangeKeys.length; i++) {
                ScoreRangeDistributionDto rangeDto = new ScoreRangeDistributionDto();
                rangeDto.setRangeKey(rangeKeys[i]);
                rangeDto.setRangeLabel(rangeLabels[i]);

                Map<Long, Integer> brigadeCountMap = rangeBrigadeCountMap.get(rangeKeys[i]);
                List<ScoreRangeDistributionDto.DeptCountItemDto> deptCounts = new ArrayList<>();
                int rangeTotalCount = 0;

                for (Map.Entry<Long, Integer> entry : brigadeCountMap.entrySet()) {
                    Long brigadeId = entry.getKey();
                    Integer count = entry.getValue();

                    ScoreRangeDistributionDto.DeptCountItemDto deptItem = new ScoreRangeDistributionDto.DeptCountItemDto();
                    deptItem.setDeptId(brigadeId);

                    SysDept brigade = deptMap.get(brigadeId);
                    if (brigade != null) {
                        deptItem.setDeptName(brigade.getDeptName());
                    }

                    deptItem.setCount(count);
                    deptCounts.add(deptItem);
                    rangeTotalCount += count;
                }

                // 设置该分数段的总人数汇总
                rangeDto.setTotalCount(rangeTotalCount);

                // 按人数降序排序
                deptCounts.sort((a, b) -> b.getCount().compareTo(a.getCount()));
                rangeDto.setDeptCounts(deptCounts);
                result.add(rangeDto);
            }

            return success(result);
        } catch (Exception e) {
            logger.error("各部门分值分布统计异常", e);
            return error("统计失败：" + e.getMessage());
        }
    }

    /**
     * 判断分数段
     */
    private String determineScoreRange(BigDecimal totalScore) {
        if (totalScore.compareTo(SCORE_90) >= 0) {
            return "above90";
        } else if (totalScore.compareTo(SCORE_85) >= 0) {
            return "85-90";
        } else if (totalScore.compareTo(SCORE_80) >= 0) {
            return "80-85";
        } else if (totalScore.compareTo(SCORE_75) >= 0) {
            return "75-80";
        } else if (totalScore.compareTo(SCORE_70) >= 0) {
            return "70-75";
        } else {
            return "below70";
        }
    }

    /**
     * 创建空的分值区间分布数据
     */
    private List<ScoreRangeDistributionDto> createEmptyScoreRangeDistribution() {
        List<ScoreRangeDistributionDto> result = new ArrayList<>();
        String[] rangeKeys = {"below70", "70-75", "75-80", "80-85", "85-90", "above90"};
        String[] rangeLabels = {"低于70", "[70-75)", "[75-80)", "[80-85)", "[85-90)", "90以上"};

        for (int i = 0; i < rangeKeys.length; i++) {
            ScoreRangeDistributionDto rangeDto = new ScoreRangeDistributionDto();
            rangeDto.setRangeKey(rangeKeys[i]);
            rangeDto.setRangeLabel(rangeLabels[i]);
            rangeDto.setDeptCounts(Collections.emptyList());
            result.add(rangeDto);
        }
        return result;
    }

    /**
     * 按月份查询数据
     */
    private List<PersonnelNonCadreMonthlyAssessment> queryByMonth(String assessmentMonth) {
        PersonnelNonCadreMonthlyAssessment query = new PersonnelNonCadreMonthlyAssessment();
        if (assessmentMonth != null && !assessmentMonth.isEmpty()) {
            query.setAssessmentMonth(assessmentMonth);
        }
        return personnelNonCadreMonthlyAssessmentService.selectPersonnelNonCadreMonthlyAssessmentList(query);
    }

    /**
     * 获取部门映射表
     */
    private Map<Long, SysDept> getDeptMap() {
        List<SysDept> allDepts = sysDeptService.selectDeptInfoAll(new SysDept());
        return allDepts.stream()
                .collect(Collectors.toMap(SysDept::getDeptId, dept -> dept, (v1, v2) -> v1));
    }

    /**
     * 构建大队到其所有子部门ID的映射
     * 用于按大队级别统计，包括大队及其下属所有部门
     *
     * @param deptMap 部门映射表
     * @return 大队ID到其所有子部门ID集合的映射
     */
    private Map<Long, Set<Long>> buildBrigadeSubDeptsMap(Map<Long, SysDept> deptMap) {
        // 获取所有大队部门
        List<SysDept> allBrigades = deptMap.values().stream()
                .filter(dept -> "BRIGADE".equals(dept.getDeptType()))
                .collect(Collectors.toList());

        // 构建大队到其所有子部门ID的映射
        Map<Long, Set<Long>> brigadeSubDeptsMap = new HashMap<>();
        for (SysDept brigade : allBrigades) {
            Set<Long> subDeptIds = getAllSubDeptIds(brigade.getDeptId(), deptMap);
            brigadeSubDeptsMap.put(brigade.getDeptId(), subDeptIds);
        }
        
        return brigadeSubDeptsMap;
    }

    /**
     * 汇总统计
     * 统计考核组人数、待改进人数、不称职人数等汇总信息
     *
     * @param assessmentMonth 考核月份（格式:YYYYMM）
     * @return 汇总统计数据
     */
    @PreAuthorize("@ss.hasPermi('personnel:assessment:query')")
    @GetMapping("/assessment-summary")
    public AjaxResult getAssessmentSummary(@RequestParam String assessmentMonth) {
        try {
            List<PersonnelNonCadreMonthlyAssessment> list = queryByMonth(assessmentMonth);

            AssessmentSummaryDto summary = new AssessmentSummaryDto();

            if (list == null || list.isEmpty()) {
                // 空数据时返回全0
                setAllZeroSummary(summary);
                return success(summary);
            }

            // 一次性遍历统计所有指标
            int assessmentTeamCount = 0;
            int improvementTotalCount = 0;
            int improvementExemptedCount = 0;
            int incompetentTotalCount = 0;
            int incompetentExemptedCount = 0;

            for (PersonnelNonCadreMonthlyAssessment item : list) {
                // 统计考核组人数
                if (item.getAssessmentTeam() != null && !item.getAssessmentTeam().isEmpty()) {
                    assessmentTeamCount++;
                }

                String assessmentResult = item.getAssessmentResult();
                String exemption = item.getExemption();

                if (RESULT_IMPROVEMENT.equals(assessmentResult)) {
                    improvementTotalCount++;
                    if (EXEMPTION_YES.equals(exemption)) {
                        improvementExemptedCount++;
                    }
                } else if (RESULT_INCOMPETENT.equals(assessmentResult)) {
                    incompetentTotalCount++;
                    if (EXEMPTION_YES.equals(exemption)) {
                        incompetentExemptedCount++;
                    }
                }
            }

            // 设置统计数据
            summary.setAssessmentTeamCount(assessmentTeamCount);

            // 2. 测算待改进人数（ROUNDUP(考核组人数*0.05,0)）
            int estimatedImprovementCount = (int) Math.ceil(assessmentTeamCount * 0.05);
            summary.setEstimatedImprovementCount(estimatedImprovementCount);

            // 3. 待改进总人数
            summary.setImprovementTotalCount(improvementTotalCount);

            // 4. 待改进豁免人数
            summary.setImprovementExemptedCount(improvementExemptedCount);

            // 5. 实际待改进人数（防止负数）
            summary.setActualImprovementCount(Math.max(0, improvementTotalCount - improvementExemptedCount));

            // 6. 不称职总人数
            summary.setIncompetentTotalCount(incompetentTotalCount);

            // 7. 不称职豁免人数
            summary.setIncompetentExemptedCount(incompetentExemptedCount);

            // 8. 实际不称职人数（防止负数）
            summary.setActualIncompetentCount(Math.max(0, incompetentTotalCount - incompetentExemptedCount));

            return success(summary);
        } catch (Exception e) {
            logger.error("汇总统计异常", e);
            return error("统计失败：" + e.getMessage());
        }
    }

    /**
     * 设置全0汇总数据
     */
    private void setAllZeroSummary(AssessmentSummaryDto summary) {
        summary.setAssessmentTeamCount(0);
        summary.setEstimatedImprovementCount(0);
        summary.setImprovementTotalCount(0);
        summary.setImprovementExemptedCount(0);
        summary.setActualImprovementCount(0);
        summary.setIncompetentTotalCount(0);
        summary.setIncompetentExemptedCount(0);
        summary.setActualIncompetentCount(0);
    }

    /**
     * 各部门实际待改进人员分布（按大队级别统计）
     * 统计所有实际待改进人员（待改进且未被豁免），按大队分类
     *
     * @param assessmentMonth 考核月份（格式:YYYYMM）
     * @return 各大队实际待改进人员分布数据
     */
    @PreAuthorize("@ss.hasPermi('personnel:assessment:query')")
    @GetMapping("/actual-improvement-distribution")
    public AjaxResult getActualImprovementDistribution(@RequestParam String assessmentMonth) {
        try {
            List<PersonnelNonCadreMonthlyAssessment> list = queryByMonth(assessmentMonth);
    
            if (list == null || list.isEmpty()) {
                return success(Collections.emptyList());
            }
    
            // 获取所有部门信息
            Map<Long, SysDept> deptMap = getDeptMap();
                
            // 构建大队到其所有子部门ID的映射
            Map<Long, Set<Long>> brigadeSubDeptsMap = buildBrigadeSubDeptsMap(deptMap);
    
            // 筛选出实际待改进人员：考核结果为“待改进”且未被豁免
            List<PersonnelNonCadreMonthlyAssessment> actualImprovementList = list.stream()
                    .filter(item -> RESULT_IMPROVEMENT.equals(item.getAssessmentResult()))
                    .filter(item -> !EXEMPTION_YES.equals(item.getExemption()))
                    .collect(Collectors.toList());
    
            if (actualImprovementList.isEmpty()) {
                return success(Collections.emptyList());
            }
    
            // 批量查询用户部门信息，避免N+1问题
            Set<Long> userIds = actualImprovementList.stream()
                    .map(PersonnelNonCadreMonthlyAssessment::getUserId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
    
            Map<Long, Long> userDeptIdMap = buildUserDeptIdMap(userIds);
    
            // 按大队统计人数
            Map<Long, Integer> brigadeCountMap = new HashMap<>();
            int totalCount = actualImprovementList.size();
    
            for (PersonnelNonCadreMonthlyAssessment item : actualImprovementList) {
                Long userDeptId = userDeptIdMap.get(item.getUserId());
                if (userDeptId != null) {
                    // 查找该用户所属的大队
                    Long brigadeId = findUserBrigade(userDeptId, brigadeSubDeptsMap);
                    if (brigadeId != null) {
                        brigadeCountMap.merge(brigadeId, 1, Integer::sum);
                    }
                }
            }
    
            // 构建返回结果
            List<DeptActualImprovementDistributionDto> result = buildDeptDistributionResult(
                    brigadeCountMap, deptMap, totalCount, DeptActualImprovementDistributionDto::new);
    
            // 按人数降序排序
            result.sort((a, b) -> b.getCount().compareTo(a.getCount()));
    
            return success(result);
        } catch (Exception e) {
            logger.error("各大队实际待改进人员分布统计异常", e);
            return error("统计失败：" + e.getMessage());
        }
    }

    /**
     * 各部门实际不称职人员分布（按大队级别统计）
     * 统计所有实际不称职人员（不称职且未被豁免），按大队分类
     *
     * @param assessmentMonth 考核月份（格式:YYYYMM）
     * @return 各大队实际不称职人员分布数据
     */
    @PreAuthorize("@ss.hasPermi('personnel:assessment:query')")
    @GetMapping("/actual-incompetent-distribution")
    public AjaxResult getActualIncompetentDistribution(@RequestParam String assessmentMonth) {
        try {
            List<PersonnelNonCadreMonthlyAssessment> list = queryByMonth(assessmentMonth);
    
            if (list == null || list.isEmpty()) {
                return success(Collections.emptyList());
            }
    
            // 获取所有部门信息
            Map<Long, SysDept> deptMap = getDeptMap();
                
            // 构建大队到其所有子部门ID的映射
            Map<Long, Set<Long>> brigadeSubDeptsMap = buildBrigadeSubDeptsMap(deptMap);
    
            // 筛选出实际不称职人员：考核结果为“不称职”且未被豁免
            List<PersonnelNonCadreMonthlyAssessment> actualIncompetentList = list.stream()
                    .filter(item -> RESULT_INCOMPETENT.equals(item.getAssessmentResult()))
                    .filter(item -> !EXEMPTION_YES.equals(item.getExemption()))
                    .collect(Collectors.toList());
    
            if (actualIncompetentList.isEmpty()) {
                return success(Collections.emptyList());
            }
    
            // 批量查询用户部门信息
            Set<Long> userIds = actualIncompetentList.stream()
                    .map(PersonnelNonCadreMonthlyAssessment::getUserId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
    
            Map<Long, Long> userDeptIdMap = buildUserDeptIdMap(userIds);
    
            // 按大队统计人数
            Map<Long, Integer> brigadeCountMap = new HashMap<>();
            int totalCount = actualIncompetentList.size();
    
            for (PersonnelNonCadreMonthlyAssessment item : actualIncompetentList) {
                Long userDeptId = userDeptIdMap.get(item.getUserId());
                if (userDeptId != null) {
                    // 查找该用户所属的大队
                    Long brigadeId = findUserBrigade(userDeptId, brigadeSubDeptsMap);
                    if (brigadeId != null) {
                        brigadeCountMap.merge(brigadeId, 1, Integer::sum);
                    }
                }
            }
    
            // 构建返回结果
            List<DeptActualIncompetentDistributionDto> result = buildDeptDistributionResult(
                    brigadeCountMap, deptMap, totalCount, DeptActualIncompetentDistributionDto::new);
    
            // 按人数降序排序
            result.sort((a, b) -> b.getCount().compareTo(a.getCount()));
    
            return success(result);
        } catch (Exception e) {
            logger.error("各大队实际不称职人员分布统计异常", e);
            return error("统计失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户所属部门ID
     */
    private Long getUserDeptId(Long userId) {
        if (userId == null) {
            return null;
        }
        SysUser user = sysUserService.selectUserById(userId);
        return user != null ? user.getDeptId() : null;
    }

    /**
     * 批量构建用户到部门的映射（批量查询，避免N+1问题）
     */
    private Map<Long, Long> buildUserDeptIdMap(Set<Long> userIds) {
        Map<Long, Long> userDeptIdMap = new HashMap<>();
        
        if (userIds == null || userIds.isEmpty()) {
            return userDeptIdMap;
        }
        
        // 批量查询用户信息
        List<SysUser> users = sysUserService.selectByUserIdList(new ArrayList<>(userIds));
        
        for (SysUser user : users) {
            if (user != null && user.getDeptId() != null) {
                userDeptIdMap.put(user.getUserId(), user.getDeptId());
            }
        }
        
        return userDeptIdMap;
    }

    /**
     * 获取指定部门及其所有子部门的ID集合
     *
     * @param deptId 部门ID
     * @param deptMap 部门映射表
     * @return 包含当前部门及所有子部门的ID集合
     */
    private Set<Long> getAllSubDeptIds(Long deptId, Map<Long, SysDept> deptMap) {
        Set<Long> result = new HashSet<>();
        result.add(deptId); // 包含当前部门
        
        for (SysDept dept : deptMap.values()) {
            if (dept.getParentId() != null && dept.getParentId().equals(deptId)) {
                // 递归获取子部门的子部门
                result.addAll(getAllSubDeptIds(dept.getDeptId(), deptMap));
            }
        }
        
        return result;
    }

    /**
     * 查找用户所属的大队ID
     *
     * @param userDeptId 用户所在部门ID
     * @param brigadeSubDeptsMap 大队到其所有子部门ID的映射
     * @return 所属大队ID，如果未找到则返回null
     */
    private Long findUserBrigade(Long userDeptId, Map<Long, Set<Long>> brigadeSubDeptsMap) {
        for (Map.Entry<Long, Set<Long>> entry : brigadeSubDeptsMap.entrySet()) {
            if (entry.getValue().contains(userDeptId)) {
                return entry.getKey();
            }
        }
        return null;
    }

    /**
     * 部门分布结果
     */
    private <T> List<T> buildDeptDistributionResult(
            Map<Long, Integer> deptCountMap,
            Map<Long, SysDept> deptMap,
            int totalCount,
            java.util.function.Supplier<T> dtoSupplier) {
        
        List<T> result = new ArrayList<>();
        
        for (Map.Entry<Long, Integer> entry : deptCountMap.entrySet()) {
            Long deptId = entry.getKey();
            Integer count = entry.getValue();

            // 通过反射设置DTO属性
            try {
                T dto = dtoSupplier.get();
                
                // 设置部门ID
                if (dto instanceof DeptActualImprovementDistributionDto) {
                    DeptActualImprovementDistributionDto improvementDto = (DeptActualImprovementDistributionDto) dto;
                    improvementDto.setDeptId(deptId);
                    SysDept dept = deptMap.get(deptId);
                    if (dept != null) {
                        improvementDto.setDeptName(dept.getDeptName());
                        improvementDto.setDeptType(dept.getDeptType());
                        improvementDto.setDeptTypeDesc(dept.getDeptTypeDesc());
                    }
                    improvementDto.setCount(count);
                    // 计算占比
                    if (totalCount > 0) {
                        BigDecimal percentage = new BigDecimal(count)
                                .divide(new BigDecimal(totalCount), 4, BigDecimal.ROUND_HALF_UP)
                                .multiply(HUNDRED);
                        improvementDto.setPercentage(percentage.setScale(1, BigDecimal.ROUND_HALF_UP));
                    } else {
                        improvementDto.setPercentage(BigDecimal.ZERO);
                    }
                } else if (dto instanceof DeptActualIncompetentDistributionDto) {
                    DeptActualIncompetentDistributionDto incompetentDto = (DeptActualIncompetentDistributionDto) dto;
                    incompetentDto.setDeptId(deptId);
                    SysDept dept = deptMap.get(deptId);
                    if (dept != null) {
                        incompetentDto.setDeptName(dept.getDeptName());
                        incompetentDto.setDeptType(dept.getDeptType());
                        incompetentDto.setDeptTypeDesc(dept.getDeptTypeDesc());
                    }
                    incompetentDto.setCount(count);
                    // 计算占比
                    if (totalCount > 0) {
                        BigDecimal percentage = new BigDecimal(count)
                                .divide(new BigDecimal(totalCount), 4, BigDecimal.ROUND_HALF_UP)
                                .multiply(HUNDRED);
                        incompetentDto.setPercentage(percentage.setScale(1, BigDecimal.ROUND_HALF_UP));
                    } else {
                        incompetentDto.setPercentage(BigDecimal.ZERO);
                    }
                }
                
                result.add(dto);
            } catch (Exception e) {
                logger.error("构建部门分布结果异常", e);
            }
        }
        
        return result;
    }

    /**
     * 各考核组实际待改进人员分布
     * 统计所有实际待改进人员（待改进且未被豁免），按考核组分类
     *
     * @param assessmentMonth 考核月份（格式:YYYYMM）
     * @return 各考核组实际待改进人员分布数据
     */
    @PreAuthorize("@ss.hasPermi('personnel:assessment:query')")
    @GetMapping("/assessment-team-improvement-distribution")
    public AjaxResult getAssessmentTeamImprovementDistribution(@RequestParam String assessmentMonth) {
        try {
            List<PersonnelNonCadreMonthlyAssessment> list = queryByMonth(assessmentMonth);

            if (list == null || list.isEmpty()) {
                return success(Collections.emptyList());
            }

            // 筛选出实际待改进人员：考核结果为"待改进"且未被豁免，且考核组不为空
            List<PersonnelNonCadreMonthlyAssessment> actualImprovementList = list.stream()
                    .filter(item -> RESULT_IMPROVEMENT.equals(item.getAssessmentResult()))
                    .filter(item -> !EXEMPTION_YES.equals(item.getExemption()))
                    .filter(item -> item.getAssessmentTeam() != null && !item.getAssessmentTeam().isEmpty())
                    .collect(Collectors.toList());

            if (actualImprovementList.isEmpty()) {
                return success(Collections.emptyList());
            }

            // 按考核组统计人数
            Map<String, Integer> teamCountMap = new HashMap<>();
            int totalCount = actualImprovementList.size();

            for (PersonnelNonCadreMonthlyAssessment item : actualImprovementList) {
                String assessmentTeam = item.getAssessmentTeam();
                if (assessmentTeam != null && !assessmentTeam.isEmpty()) {
                    teamCountMap.merge(assessmentTeam, 1, Integer::sum);
                }
            }

            // 构建返回结果
            List<AssessmentTeamActualImprovementDistributionDto> result = new ArrayList<>();
            for (Map.Entry<String, Integer> entry : teamCountMap.entrySet()) {
                String assessmentTeam = entry.getKey();
                Integer count = entry.getValue();

                AssessmentTeamActualImprovementDistributionDto dto = new AssessmentTeamActualImprovementDistributionDto();
                dto.setAssessmentTeam(assessmentTeam);
                dto.setCount(count);

                // 计算占比
                if (totalCount > 0) {
                    BigDecimal percentage = new BigDecimal(count)
                            .divide(new BigDecimal(totalCount), 4, BigDecimal.ROUND_HALF_UP)
                            .multiply(HUNDRED);
                    dto.setPercentage(percentage.setScale(1, BigDecimal.ROUND_HALF_UP));
                } else {
                    dto.setPercentage(BigDecimal.ZERO);
                }

                result.add(dto);
            }

            // 按人数降序排序
            result.sort((a, b) -> b.getCount().compareTo(a.getCount()));

            return success(result);
        } catch (Exception e) {
            logger.error("各考核组实际待改进人员分布统计异常", e);
            return error("统计失败：" + e.getMessage());
        }
    }

    /**
     * 各考核组实际不称职人员分布
     * 统计所有实际不称职人员（不称职且未被豁免），按考核组分类
     *
     * @param assessmentMonth 考核月份（格式:YYYYMM）
     * @return 各考核组实际不称职人员分布数据
     */
    @PreAuthorize("@ss.hasPermi('personnel:assessment:query')")
    @GetMapping("/assessment-team-incompetent-distribution")
    public AjaxResult getAssessmentTeamIncompetentDistribution(@RequestParam String assessmentMonth) {
        try {
            List<PersonnelNonCadreMonthlyAssessment> list = queryByMonth(assessmentMonth);

            if (list == null || list.isEmpty()) {
                return success(Collections.emptyList());
            }

            // 筛选出实际不称职人员：考核结果为"不称职"且未被豁免，且考核组不为空
            List<PersonnelNonCadreMonthlyAssessment> actualIncompetentList = list.stream()
                    .filter(item -> RESULT_INCOMPETENT.equals(item.getAssessmentResult()))
                    .filter(item -> !EXEMPTION_YES.equals(item.getExemption()))
                    .filter(item -> item.getAssessmentTeam() != null && !item.getAssessmentTeam().isEmpty())
                    .collect(Collectors.toList());

            if (actualIncompetentList.isEmpty()) {
                return success(Collections.emptyList());
            }

            // 按考核组统计人数
            Map<String, Integer> teamCountMap = new HashMap<>();
            int totalCount = actualIncompetentList.size();

            for (PersonnelNonCadreMonthlyAssessment item : actualIncompetentList) {
                String assessmentTeam = item.getAssessmentTeam();
                if (assessmentTeam != null && !assessmentTeam.isEmpty()) {
                    teamCountMap.merge(assessmentTeam, 1, Integer::sum);
                }
            }

            // 构建返回结果
            List<AssessmentTeamActualIncompetentDistributionDto> result = new ArrayList<>();
            for (Map.Entry<String, Integer> entry : teamCountMap.entrySet()) {
                String assessmentTeam = entry.getKey();
                Integer count = entry.getValue();

                AssessmentTeamActualIncompetentDistributionDto dto = new AssessmentTeamActualIncompetentDistributionDto();
                dto.setAssessmentTeam(assessmentTeam);
                dto.setCount(count);

                // 计算占比
                if (totalCount > 0) {
                    BigDecimal percentage = new BigDecimal(count)
                            .divide(new BigDecimal(totalCount), 4, BigDecimal.ROUND_HALF_UP)
                            .multiply(HUNDRED);
                    dto.setPercentage(percentage.setScale(1, BigDecimal.ROUND_HALF_UP));
                } else {
                    dto.setPercentage(BigDecimal.ZERO);
                }

                result.add(dto);
            }

            // 按人数降序排序
            result.sort((a, b) -> b.getCount().compareTo(a.getCount()));

            return success(result);
        } catch (Exception e) {
            logger.error("各考核组实际不称职人员分布统计异常", e);
            return error("统计失败：" + e.getMessage());
        }
    }



    /**
     * 大队考核组统计
     * 先按大队筛选，再按考核组统计，应用汇总统计规则
     *
     * @param assessmentMonth 考核月份（格式:YYYYMM）
     * @param deptId 大队ID（可选，不传则返回所有大队）
     * @return 各大队及其考核组的统计数据
     */
    @PreAuthorize("@ss.hasPermi('personnel:assessment:query')")
    @GetMapping("/dept-assessment-team-statistics")
    public AjaxResult getDeptAssessmentTeamStatistics(
            @RequestParam String assessmentMonth,
            @RequestParam(required = false) Long deptId) {
        try {
            List<PersonnelNonCadreMonthlyAssessment> allList = queryByMonth(assessmentMonth);

            if (allList == null || allList.isEmpty()) {
                return success(Collections.emptyList());
            }

            // 获取所有部门信息，建立映射
            Map<Long, SysDept> deptIdMap = getDeptMap();

            Set<Long> userIds = allList.stream()
                    .map(PersonnelNonCadreMonthlyAssessment::getUserId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());

            Map<Long, Long> userDeptIdMap = buildUserDeptIdMap(userIds);

            // 如果指定了大队ID，先筛选该大队的人员（包括大队及其所有子部门）
            List<PersonnelNonCadreMonthlyAssessment> filteredList = allList;
            if (deptId != null) {
                // 获取该大队及其所有子部门的ID集合
                Set<Long> brigadeSubDeptIds = getAllSubDeptIds(deptId, deptIdMap);
                
                filteredList = allList.stream()
                        .filter(item -> {
                            Long userDeptId = userDeptIdMap.get(item.getUserId());
                            return userDeptId != null && brigadeSubDeptIds.contains(userDeptId);
                        })
                        .collect(Collectors.toList());
            }

            // 按大队分组
            Map<String, List<PersonnelNonCadreMonthlyAssessment>> deptGroupMap = filteredList.stream()
                    .filter(item -> item.getUserId() != null)
                    .collect(Collectors.groupingBy(item -> {
                        Long userDeptId = userDeptIdMap.get(item.getUserId());
                        if (userDeptId == null) {
                            return "未知部门";
                        }
                        SysDept dept = deptIdMap.get(userDeptId);
                        return dept != null ? dept.getDeptName() : "未知部门";
                    }));

            // 构建返回结果
            List<DeptAssessmentTeamStatisticsDto> result = new ArrayList<>();

            for (Map.Entry<String, List<PersonnelNonCadreMonthlyAssessment>> deptEntry : deptGroupMap.entrySet()) {
                String currentDeptName = deptEntry.getKey();
                List<PersonnelNonCadreMonthlyAssessment> deptRecords = deptEntry.getValue();

                DeptAssessmentTeamStatisticsDto deptDto = new DeptAssessmentTeamStatisticsDto();
                deptDto.setDeptName(currentDeptName);

                // 按考核组分组
                Map<String, List<PersonnelNonCadreMonthlyAssessment>> teamGroupMap = deptRecords.stream()
                        .filter(item -> item.getAssessmentTeam() != null && !item.getAssessmentTeam().isEmpty())
                        .collect(Collectors.groupingBy(PersonnelNonCadreMonthlyAssessment::getAssessmentTeam));

                List<DeptAssessmentTeamStatisticsDto.AssessmentTeamStatisticsDto> teamStatsList = new ArrayList<>();

                for (Map.Entry<String, List<PersonnelNonCadreMonthlyAssessment>> teamEntry : teamGroupMap.entrySet()) {
                    String assessmentTeam = teamEntry.getKey();
                    List<PersonnelNonCadreMonthlyAssessment> teamRecords = teamEntry.getValue();

                    DeptAssessmentTeamStatisticsDto.AssessmentTeamStatisticsDto teamDto =
                            calculateTeamStatistics(assessmentTeam, teamRecords);

                    teamStatsList.add(teamDto);
                }

                deptDto.setAssessmentTeams(teamStatsList);
                result.add(deptDto);
            }

            return success(result);
        } catch (Exception e) {
            logger.error("大队考核组统计异常", e);
            return error("统计失败：" + e.getMessage());
        }
    }

    /**
     * 计算考核组统计数据（一次性遍历完成所有统计）
     */
    private DeptAssessmentTeamStatisticsDto.AssessmentTeamStatisticsDto calculateTeamStatistics(
            String assessmentTeam, List<PersonnelNonCadreMonthlyAssessment> teamRecords) {
        
        DeptAssessmentTeamStatisticsDto.AssessmentTeamStatisticsDto teamDto =
                new DeptAssessmentTeamStatisticsDto.AssessmentTeamStatisticsDto();
        teamDto.setAssessmentTeam(assessmentTeam);

        // 1. 考核组人数
        int assessmentTeamCount = teamRecords.size();
        teamDto.setAssessmentTeamCount(assessmentTeamCount);

        // 2. 测算待改进人数（ROUNDUP(考核组人数*0.05,0)）
        int estimatedImprovementCount = (int) Math.ceil(assessmentTeamCount * 0.05);
        teamDto.setEstimatedImprovementCount(estimatedImprovementCount);

        // 一次性遍历统计其他指标
        int improvementTotalCount = 0;
        int improvementExemptedCount = 0;
        int incompetentTotalCount = 0;
        int incompetentExemptedCount = 0;

        for (PersonnelNonCadreMonthlyAssessment item : teamRecords) {
            String assessmentResult = item.getAssessmentResult();
            String exemption = item.getExemption();

            if (RESULT_IMPROVEMENT.equals(assessmentResult)) {
                improvementTotalCount++;
                if (EXEMPTION_YES.equals(exemption)) {
                    improvementExemptedCount++;
                }
            } else if (RESULT_INCOMPETENT.equals(assessmentResult)) {
                incompetentTotalCount++;
                if (EXEMPTION_YES.equals(exemption)) {
                    incompetentExemptedCount++;
                }
            }
        }

        // 3. 待改进总人数
        teamDto.setImprovementTotalCount(improvementTotalCount);

        // 4. 待改进豁免人数
        teamDto.setImprovementExemptedCount(improvementExemptedCount);

        // 5. 实际待改进人数（防止负数）
        teamDto.setActualImprovementCount(Math.max(0, improvementTotalCount - improvementExemptedCount));

        // 6. 不称职总人数
        teamDto.setIncompetentTotalCount(incompetentTotalCount);

        // 7. 不称职豁免人数
        teamDto.setIncompetentExemptedCount(incompetentExemptedCount);

        // 8. 实际不称职人数（防止负数）
        teamDto.setActualIncompetentCount(Math.max(0, incompetentTotalCount - incompetentExemptedCount));

        return teamDto;
    }

    /**
     * 创建空分数分布数据
     */
    private List<ScoreDistributionDto> createEmptyScoreDistribution() {
        List<ScoreDistributionDto> result = new ArrayList<>();
        String[] ranges = {"90分以上", "85-89分", "80-84分", "70-79分", "69分及以下", "总计"};
        for (String range : ranges) {
            ScoreDistributionDto dto = new ScoreDistributionDto();
            dto.setScoreRange(range);
            dto.setCount(0);
            result.add(dto);
        }
        return result;
    }

    /**
     * 大队实际待改进人员分布
     * 统计指定大队所有实际待改进人员（待改进且未被豁免），按考核组分类
     *
     * @param assessmentMonth 考核月份（格式:YYYYMM）
     * @param deptId 大队ID
     * @return 指定大队各考核组实际待改进人员分布数据
     */
    @PreAuthorize("@ss.hasPermi('personnel:assessment:query')")
    @GetMapping("/brigade-improvement-distribution")
    public AjaxResult getBrigadeImprovementDistribution(
            @RequestParam String assessmentMonth,
            @RequestParam Long deptId) {
        try {
            List<PersonnelNonCadreMonthlyAssessment> allList = queryByMonth(assessmentMonth);

            if (allList == null || allList.isEmpty()) {
                return success(Collections.emptyList());
            }
            
            // 获取所有部门信息
            Map<Long, SysDept> deptMap = getDeptMap();
            
            Set<Long> userIds = allList.stream()
                    .map(PersonnelNonCadreMonthlyAssessment::getUserId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            
            Map<Long, Long> userDeptIdMap = buildUserDeptIdMap(userIds);
            
            // 获取该大队及其所有子部门的ID集合
            Set<Long> brigadeSubDeptIds = getAllSubDeptIds(deptId, deptMap);
            
            // 筛选指定大队的实际待改进人员：属于该大队（包括子部门）、考核结果为“待改进”且未被豁免、考核组不为空
            List<PersonnelNonCadreMonthlyAssessment> actualImprovementList = allList.stream()
                    .filter(item -> {
                        Long userDeptId = userDeptIdMap.get(item.getUserId());
                        return userDeptId != null && brigadeSubDeptIds.contains(userDeptId);
                    })
                    .filter(item -> RESULT_IMPROVEMENT.equals(item.getAssessmentResult()))
                    .filter(item -> !EXEMPTION_YES.equals(item.getExemption()))
                    .filter(item -> item.getAssessmentTeam() != null && !item.getAssessmentTeam().isEmpty())
                    .collect(Collectors.toList());

            if (actualImprovementList.isEmpty()) {
                return success(Collections.emptyList());
            }

            // 按考核组统计人数
            Map<String, Integer> teamCountMap = new HashMap<>();
            int totalCount = actualImprovementList.size();

            for (PersonnelNonCadreMonthlyAssessment item : actualImprovementList) {
                String assessmentTeam = item.getAssessmentTeam();
                if (assessmentTeam != null && !assessmentTeam.isEmpty()) {
                    teamCountMap.merge(assessmentTeam, 1, Integer::sum);
                }
            }

            // 构建返回结果
            List<AssessmentTeamActualImprovementDistributionDto> result = new ArrayList<>();
            for (Map.Entry<String, Integer> entry : teamCountMap.entrySet()) {
                String assessmentTeam = entry.getKey();
                Integer count = entry.getValue();

                AssessmentTeamActualImprovementDistributionDto dto = new AssessmentTeamActualImprovementDistributionDto();
                dto.setAssessmentTeam(assessmentTeam);
                dto.setCount(count);

                // 计算占比
                if (totalCount > 0) {
                    BigDecimal percentage = new BigDecimal(count)
                            .divide(new BigDecimal(totalCount), 4, BigDecimal.ROUND_HALF_UP)
                            .multiply(HUNDRED);
                    dto.setPercentage(percentage.setScale(1, BigDecimal.ROUND_HALF_UP));
                } else {
                    dto.setPercentage(BigDecimal.ZERO);
                }

                result.add(dto);
            }

            // 按人数降序排序
            result.sort((a, b) -> b.getCount().compareTo(a.getCount()));

            return success(result);
        } catch (Exception e) {
            logger.error("大队实际待改进人员分布统计异常", e);
            return error("统计失败：" + e.getMessage());
        }
    }

    /**
     * 大队实际不称职人员分布
     * 统计指定大队所有实际不称职人员（不称职且未被豁免），按考核组分类
     *
     * @param assessmentMonth 考核月份（格式:YYYYMM）
     * @param deptId 大队ID
     * @return 指定大队各考核组实际不称职人员分布数据
     */
    @PreAuthorize("@ss.hasPermi('personnel:assessment:query')")
    @GetMapping("/brigade-incompetent-distribution")
    public AjaxResult getBrigadeIncompetentDistribution(
            @RequestParam String assessmentMonth,
            @RequestParam Long deptId) {
        try {
            List<PersonnelNonCadreMonthlyAssessment> allList = queryByMonth(assessmentMonth);

            if (allList == null || allList.isEmpty()) {
                return success(Collections.emptyList());
            }
            
            // 获取所有部门信息
            Map<Long, SysDept> deptMap = getDeptMap();
            
            Set<Long> userIds = allList.stream()
                    .map(PersonnelNonCadreMonthlyAssessment::getUserId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            
            Map<Long, Long> userDeptIdMap = buildUserDeptIdMap(userIds);
            
            // 获取该大队及其所有子部门的ID集合
            Set<Long> brigadeSubDeptIds = getAllSubDeptIds(deptId, deptMap);
            
            // 筛选指定大队的实际不称职人员：属于该大队（包括子部门）、考核结果为“不称职”且未被豁免、考核组不为空
            List<PersonnelNonCadreMonthlyAssessment> actualIncompetentList = allList.stream()
                    .filter(item -> {
                        Long userDeptId = userDeptIdMap.get(item.getUserId());
                        return userDeptId != null && brigadeSubDeptIds.contains(userDeptId);
                    })
                    .filter(item -> RESULT_INCOMPETENT.equals(item.getAssessmentResult()))
                    .filter(item -> !EXEMPTION_YES.equals(item.getExemption()))
                    .filter(item -> item.getAssessmentTeam() != null && !item.getAssessmentTeam().isEmpty())
                    .collect(Collectors.toList());

            if (actualIncompetentList.isEmpty()) {
                return success(Collections.emptyList());
            }

            // 按考核组统计人数
            Map<String, Integer> teamCountMap = new HashMap<>();
            int totalCount = actualIncompetentList.size();

            for (PersonnelNonCadreMonthlyAssessment item : actualIncompetentList) {
                String assessmentTeam = item.getAssessmentTeam();
                if (assessmentTeam != null && !assessmentTeam.isEmpty()) {
                    teamCountMap.merge(assessmentTeam, 1, Integer::sum);
                }
            }

            // 构建返回结果
            List<AssessmentTeamActualIncompetentDistributionDto> result = new ArrayList<>();
            for (Map.Entry<String, Integer> entry : teamCountMap.entrySet()) {
                String assessmentTeam = entry.getKey();
                Integer count = entry.getValue();

                AssessmentTeamActualIncompetentDistributionDto dto = new AssessmentTeamActualIncompetentDistributionDto();
                dto.setAssessmentTeam(assessmentTeam);
                dto.setCount(count);

                // 计算占比
                if (totalCount > 0) {
                    BigDecimal percentage = new BigDecimal(count)
                            .divide(new BigDecimal(totalCount), 4, BigDecimal.ROUND_HALF_UP)
                            .multiply(HUNDRED);
                    dto.setPercentage(percentage.setScale(1, BigDecimal.ROUND_HALF_UP));
                } else {
                    dto.setPercentage(BigDecimal.ZERO);
                }

                result.add(dto);
            }

            // 按人数降序排序
            result.sort((a, b) -> b.getCount().compareTo(a.getCount()));

            return success(result);
        } catch (Exception e) {
            logger.error("大队实际不称职人员分布统计异常", e);
            return error("统计失败：" + e.getMessage());
        }
    }

    /**
     * 各职能大队汇总
     * 统计所有职能部门
     *
     * @param assessmentMonth 考核月份（格式:YYYYMM）
     * @return 各职能大队汇总数据，包含小计
     */
    @PreAuthorize("@ss.hasPermi('personnel:assessment:query')")
    @GetMapping("/functional-dept-summary")
    public AjaxResult getFunctionalDeptSummary(@RequestParam String assessmentMonth) {
        try {
            List<PersonnelNonCadreMonthlyAssessment> allList = queryByMonth(assessmentMonth);

            if (allList == null || allList.isEmpty()) {
                return success(Collections.emptyList());
            }

            // 获取所有部门信息
            Map<Long, SysDept> deptMap = getDeptMap();

            // 查询用户部门映射
            Set<Long> userIds = allList.stream()
                    .map(PersonnelNonCadreMonthlyAssessment::getUserId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            Map<Long, Long> userDeptIdMap = buildUserDeptIdMap(userIds);

            // 筛选所有职能部门（is_functional_dept='1'）
            List<SysDept> functionalDepts = deptMap.values().stream()
                    .filter(dept -> "1".equals(dept.getIsFunctionalDept()))
                    .collect(Collectors.toList());

            if (functionalDepts.isEmpty()) {
                return success(Collections.emptyList());
            }

            // 用于累加小计数据
            int totalAssessmentTeamCount = 0;
            int totalEstimatedImprovementCount = 0;
            int totalImprovementTotalCount = 0;
            int totalImprovementExemptedCount = 0;
            int totalActualImprovementCount = 0;
            int totalIncompetentTotalCount = 0;
            int totalIncompetentExemptedCount = 0;
            int totalActualIncompetentCount = 0;

            // 构建返回结果
            List<FunctionalDeptSummaryDto> result = new ArrayList<>();

            for (SysDept functionalDept : functionalDepts) {
                Long deptId = functionalDept.getDeptId();
                String deptName = functionalDept.getDeptName();

                // 获取该职能部门及其所有子部门的ID集合
                Set<Long> functionalSubDeptIds = getAllSubDeptIds(deptId, deptMap);

                // 筛选属于该职能部门的人员（包括子部门）
                List<PersonnelNonCadreMonthlyAssessment> deptRecords = allList.stream()
                        .filter(item -> {
                            Long userDeptId = userDeptIdMap.get(item.getUserId());
                            return userDeptId != null && functionalSubDeptIds.contains(userDeptId);
                        })
                        .collect(Collectors.toList());

                if (deptRecords.isEmpty()) {
                    continue;
                }

                // 按考核组分组
                Map<String, List<PersonnelNonCadreMonthlyAssessment>> teamGroupMap = deptRecords.stream()
                        .filter(item -> item.getAssessmentTeam() != null && !item.getAssessmentTeam().isEmpty())
                        .collect(Collectors.groupingBy(PersonnelNonCadreMonthlyAssessment::getAssessmentTeam));

                List<FunctionalDeptSummaryDto.FunctionalTeamStatisticsDto> teamStatsList = new ArrayList<>();

                for (Map.Entry<String, List<PersonnelNonCadreMonthlyAssessment>> teamEntry : teamGroupMap.entrySet()) {
                    String assessmentTeam = teamEntry.getKey();
                    List<PersonnelNonCadreMonthlyAssessment> teamRecords = teamEntry.getValue();

                    // 统计该考核组的数据
                    int assessmentTeamCount = teamRecords.size();
                    int estimatedImprovementCount = (int) Math.ceil(assessmentTeamCount * 0.05);

                    int improvementTotalCount = 0;
                    int improvementExemptedCount = 0;
                    int incompetentTotalCount = 0;
                    int incompetentExemptedCount = 0;

                    for (PersonnelNonCadreMonthlyAssessment item : teamRecords) {
                        String assessmentResult = item.getAssessmentResult();
                        String exemption = item.getExemption();

                        if (RESULT_IMPROVEMENT.equals(assessmentResult)) {
                            improvementTotalCount++;
                            if (EXEMPTION_YES.equals(exemption)) {
                                improvementExemptedCount++;
                            }
                        } else if (RESULT_INCOMPETENT.equals(assessmentResult)) {
                            incompetentTotalCount++;
                            if (EXEMPTION_YES.equals(exemption)) {
                                incompetentExemptedCount++;
                            }
                        }
                    }

                    int actualImprovementCount = Math.max(0, improvementTotalCount - improvementExemptedCount);
                    int actualIncompetentCount = Math.max(0, incompetentTotalCount - incompetentExemptedCount);

                    // 构建考核组统计数据
                    FunctionalDeptSummaryDto.FunctionalTeamStatisticsDto teamDto =
                            new FunctionalDeptSummaryDto.FunctionalTeamStatisticsDto();
                    teamDto.setAssessmentTeam(assessmentTeam);
                    teamDto.setAssessmentTeamCount(assessmentTeamCount);
                    teamDto.setEstimatedImprovementCount(estimatedImprovementCount);
                    teamDto.setImprovementTotalCount(improvementTotalCount);
                    teamDto.setImprovementExemptedCount(improvementExemptedCount);
                    teamDto.setActualImprovementCount(actualImprovementCount);
                    teamDto.setIncompetentTotalCount(incompetentTotalCount);
                    teamDto.setIncompetentExemptedCount(incompetentExemptedCount);
                    teamDto.setActualIncompetentCount(actualIncompetentCount);

                    teamStatsList.add(teamDto);

                    // 累加到小计
                    totalAssessmentTeamCount += assessmentTeamCount;
                    totalEstimatedImprovementCount += estimatedImprovementCount;
                    totalImprovementTotalCount += improvementTotalCount;
                    totalImprovementExemptedCount += improvementExemptedCount;
                    totalActualImprovementCount += actualImprovementCount;
                    totalIncompetentTotalCount += incompetentTotalCount;
                    totalIncompetentExemptedCount += incompetentExemptedCount;
                    totalActualIncompetentCount += actualIncompetentCount;
                }

                // 构建职能部门统计数据
                FunctionalDeptSummaryDto deptDto = new FunctionalDeptSummaryDto();
                deptDto.setDeptId(deptId);
                deptDto.setDeptName(deptName);
                deptDto.setAssessmentTeams(teamStatsList);
                result.add(deptDto);
            }

            // 添加小计行（合并所有考核组的数据）
            FunctionalDeptSummaryDto.FunctionalTeamStatisticsDto summaryDto =
                    new FunctionalDeptSummaryDto.FunctionalTeamStatisticsDto();
            summaryDto.setAssessmentTeam("小计");
            summaryDto.setAssessmentTeamCount(totalAssessmentTeamCount);
            summaryDto.setEstimatedImprovementCount(totalEstimatedImprovementCount);
            summaryDto.setImprovementTotalCount(totalImprovementTotalCount);
            summaryDto.setImprovementExemptedCount(totalImprovementExemptedCount);
            summaryDto.setActualImprovementCount(totalActualImprovementCount);
            summaryDto.setIncompetentTotalCount(totalIncompetentTotalCount);
            summaryDto.setIncompetentExemptedCount(totalIncompetentExemptedCount);
            summaryDto.setActualIncompetentCount(totalActualIncompetentCount);

            // 将小计作为一个单独的部门添加到结果中
            FunctionalDeptSummaryDto summaryDept = new FunctionalDeptSummaryDto();
            summaryDept.setDeptName("小计");
            summaryDept.setAssessmentTeams(Collections.singletonList(summaryDto));
            result.add(summaryDept);

            return success(result);
        } catch (Exception e) {
            logger.error("各职能大队汇总统计异常", e);
            return error("统计失败：" + e.getMessage());
        }
    }


    /**
     * 各职能部门待改进、不称职人员分布
     *
     * @param assessmentMonth 考核月份（格式:YYYYMM）
     * @return 各职能部门人员分布数据
     */
    @PreAuthorize("@ss.hasPermi('personnel:assessment:query')")
    @GetMapping("/functional-dept-personnel-distribution")
    public AjaxResult getFunctionalDeptPersonnelDistribution(@RequestParam String assessmentMonth) {
        try {
            List<PersonnelNonCadreMonthlyAssessment> allList = queryByMonth(assessmentMonth);

            if (allList == null || allList.isEmpty()) {
                return success(Collections.emptyList());
            }

            // 获取所有部门信息
            Map<Long, SysDept> deptMap = getDeptMap();

            // 查询用户部门映射
            Set<Long> userIds = allList.stream()
                    .map(PersonnelNonCadreMonthlyAssessment::getUserId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            Map<Long, Long> userDeptIdMap = buildUserDeptIdMap(userIds);

            // 筛选所有职能部门（is_functional_dept='1'）
            List<SysDept> functionalDepts = deptMap.values().stream()
                    .filter(dept -> "1".equals(dept.getIsFunctionalDept()))
                    .collect(Collectors.toList());

            if (functionalDepts.isEmpty()) {
                return success(Collections.emptyList());
            }

            // 构建返回结果
            List<FunctionalDeptPersonnelDistributionDto> result = new ArrayList<>();

            for (SysDept functionalDept : functionalDepts) {
                Long deptId = functionalDept.getDeptId();
                String deptName = functionalDept.getDeptName();

                // 获取该职能部门及其所有子部门的ID集合
                Set<Long> functionalSubDeptIds = getAllSubDeptIds(deptId, deptMap);

                // 筛选属于该职能部门的人员（包括子部门）
                List<PersonnelNonCadreMonthlyAssessment> deptRecords = allList.stream()
                        .filter(item -> {
                            Long userDeptId = userDeptIdMap.get(item.getUserId());
                            return userDeptId != null && functionalSubDeptIds.contains(userDeptId);
                        })
                        .filter(item -> item.getAssessmentTeam() != null && !item.getAssessmentTeam().isEmpty())
                        .collect(Collectors.toList());

                if (deptRecords.isEmpty()) {
                    continue;
                }

                // 统计考核组人数
                int assessmentTeamCount = deptRecords.size();

                // 统计实际待改进人数：考核结果为"待改进"且未被豁免
                long actualImprovementCount = deptRecords.stream()
                        .filter(item -> RESULT_IMPROVEMENT.equals(item.getAssessmentResult()))
                        .filter(item -> !EXEMPTION_YES.equals(item.getExemption()))
                        .count();

                // 统计实际不称职人数：考核结果为"不称职"且未被豁免
                long actualIncompetentCount = deptRecords.stream()
                        .filter(item -> RESULT_INCOMPETENT.equals(item.getAssessmentResult()))
                        .filter(item -> !EXEMPTION_YES.equals(item.getExemption()))
                        .count();

                // 构建DTO
                FunctionalDeptPersonnelDistributionDto dto = new FunctionalDeptPersonnelDistributionDto();
                dto.setDeptId(deptId);
                dto.setDeptName(deptName);
                dto.setAssessmentTeamCount(assessmentTeamCount);
                dto.setActualImprovementCount((int) actualImprovementCount);
                dto.setActualIncompetentCount((int) actualIncompetentCount);

                result.add(dto);
            }

            // 按考核组人数降序排序
            result.sort((a, b) -> b.getAssessmentTeamCount().compareTo(a.getAssessmentTeamCount()));

            return success(result);
        } catch (Exception e) {
            logger.error("各职能部门人员分布统计异常", e);
            return error("统计失败：" + e.getMessage());
        }
    }

    /**
     * 各职能考核人员分布（饼图数据）
     * 统计所有职能部门（is_functional_dept='1'）的考核组人数及占比
     *
     * @param assessmentMonth 考核月份（格式:YYYYMM）
     * @return 各职能考核人员分布数据
     */
    @PreAuthorize("@ss.hasPermi('personnel:assessment:query')")
    @GetMapping("/functional-dept-distribution-pie")
    public AjaxResult getFunctionalDeptDistributionPie(@RequestParam String assessmentMonth) {
        try {
            List<PersonnelNonCadreMonthlyAssessment> allList = queryByMonth(assessmentMonth);

            if (allList == null || allList.isEmpty()) {
                return success(Collections.emptyList());
            }

            // 获取所有部门信息
            Map<Long, SysDept> deptMap = getDeptMap();

            // 查询用户部门映射
            Set<Long> userIds = allList.stream()
                    .map(PersonnelNonCadreMonthlyAssessment::getUserId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            Map<Long, Long> userDeptIdMap = buildUserDeptIdMap(userIds);

            // 筛选所有职能部门（is_functional_dept='1'）
            List<SysDept> functionalDepts = deptMap.values().stream()
                    .filter(dept -> "1".equals(dept.getIsFunctionalDept()))
                    .collect(Collectors.toList());

            if (functionalDepts.isEmpty()) {
                return success(Collections.emptyList());
            }

            // 统计总人数
            int totalCount = 0;

            // 先统计各职能部门人数
            Map<Long, Integer> deptCountMap = new HashMap<>();
            Map<Long, String> deptNameMap = new HashMap<>();
            Map<Long, String> deptTeamMap = new HashMap<>();

            for (SysDept functionalDept : functionalDepts) {
                Long deptId = functionalDept.getDeptId();
                String deptName = functionalDept.getDeptName();

                // 获取该职能部门及其所有子部门的ID集合
                Set<Long> functionalSubDeptIds = getAllSubDeptIds(deptId, deptMap);

                // 筛选属于该职能部门的人员（包括子部门）
                List<PersonnelNonCadreMonthlyAssessment> deptRecords = allList.stream()
                        .filter(item -> {
                            Long userDeptId = userDeptIdMap.get(item.getUserId());
                            return userDeptId != null && functionalSubDeptIds.contains(userDeptId);
                        })
                        .filter(item -> item.getAssessmentTeam() != null && !item.getAssessmentTeam().isEmpty())
                        .collect(Collectors.toList());

                if (!deptRecords.isEmpty()) {
                    int count = deptRecords.size();
                    deptCountMap.put(deptId, count);
                    deptNameMap.put(deptId, deptName);
                    // 获取考核组名称（取第一个非空考核组）
                    String assessmentTeam = deptRecords.get(0).getAssessmentTeam();
                    deptTeamMap.put(deptId, assessmentTeam);
                    totalCount += count;
                }
            }

            // 构建返回结果
            List<FunctionalDeptDistributionPieDto> result = new ArrayList<>();
            for (Map.Entry<Long, Integer> entry : deptCountMap.entrySet()) {
                Long deptId = entry.getKey();
                Integer count = entry.getValue();

                FunctionalDeptDistributionPieDto dto = new FunctionalDeptDistributionPieDto();
                dto.setDeptId(deptId);
                dto.setDeptName(deptNameMap.get(deptId));
                dto.setAssessmentTeam(deptTeamMap.get(deptId));
                dto.setCount(count);

                // 计算占比
                if (totalCount > 0) {
                    BigDecimal percentage = new BigDecimal(count)
                            .divide(new BigDecimal(totalCount), 4, BigDecimal.ROUND_HALF_UP)
                            .multiply(HUNDRED);
                    dto.setPercentage(percentage.setScale(1, BigDecimal.ROUND_HALF_UP));
                } else {
                    dto.setPercentage(BigDecimal.ZERO);
                }

                result.add(dto);
            }

            // 按人数降序排序
            result.sort((a, b) -> b.getCount().compareTo(a.getCount()));

            return success(result);
        } catch (Exception e) {
            logger.error("各职能考核人员分布统计异常", e);
            return error("统计失败：" + e.getMessage());
        }
    }


}
