package com.sundot.airport.personnel.service.impl;

import com.sundot.airport.common.core.domain.entity.SysDept;
import com.sundot.airport.common.core.domain.entity.SysUser;
import com.sundot.airport.common.exception.ServiceException;
import com.sundot.airport.personnel.domain.PersonnelMonthlyAssessment;
import com.sundot.airport.personnel.mapper.PersonnelMonthlyAssessmentMapper;
import com.sundot.airport.personnel.service.IPersonnelMonthlyAssessmentService;
import com.sundot.airport.system.mapper.SysDeptMapper;
import com.sundot.airport.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 人员月度考核Service业务层处理
 *
 * @author ruoyi
 * @date 2026-05-07
 */
@Service
public class PersonnelMonthlyAssessmentServiceImpl implements IPersonnelMonthlyAssessmentService {
    @Autowired
    private PersonnelMonthlyAssessmentMapper personnelMonthlyAssessmentMapper;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 查询人员月度考核
     *
     * @param id 人员月度考核主键
     * @return 人员月度考核
     */
    @Override
    public PersonnelMonthlyAssessment selectPersonnelMonthlyAssessmentById(Long id) {
        return personnelMonthlyAssessmentMapper.selectPersonnelMonthlyAssessmentById(id);
    }

    /**
     * 查询人员月度考核列表
     *
     * @param personnelMonthlyAssessment 人员月度考核
     * @return 人员月度考核
     */
    @Override
    public List<PersonnelMonthlyAssessment> selectPersonnelMonthlyAssessmentList(PersonnelMonthlyAssessment personnelMonthlyAssessment) {
        return personnelMonthlyAssessmentMapper.selectPersonnelMonthlyAssessmentList(personnelMonthlyAssessment);
    }

    /**
     * 新增人员月度考核
     *
     * @param personnelMonthlyAssessment 人员月度考核
     * @return 结果
     */
    @Override
    public int insertPersonnelMonthlyAssessment(PersonnelMonthlyAssessment personnelMonthlyAssessment) {
        // 校验同一用户同一年份月份是否已存在考核记录
        PersonnelMonthlyAssessment existing = personnelMonthlyAssessmentMapper.selectByUserIdAndYearMonth(
                personnelMonthlyAssessment.getUserId(),
                personnelMonthlyAssessment.getYear(),
                personnelMonthlyAssessment.getMonth()
        );
        if (existing != null) {
            throw new ServiceException("该用户在此考核月份已存在考核记录，请勿重复添加！");
        }

        // 计算总分：100 - 红线扣分 - 违规排名扣分 - 技能排名扣分
        calculateTotalScore(personnelMonthlyAssessment);

        return personnelMonthlyAssessmentMapper.insertPersonnelMonthlyAssessment(personnelMonthlyAssessment);
    }

    /**
     * 修改人员月度考核
     *
     * @param personnelMonthlyAssessment 人员月度考核
     * @return 结果
     */
    @Override
    public int updatePersonnelMonthlyAssessment(PersonnelMonthlyAssessment personnelMonthlyAssessment) {
        // 计算总分：100 - 红线扣分 - 违规排名扣分 - 技能排名扣分
        calculateTotalScore(personnelMonthlyAssessment);

        return personnelMonthlyAssessmentMapper.updatePersonnelMonthlyAssessment(personnelMonthlyAssessment);
    }

    /**
     * 批量删除人员月度考核
     *
     * @param ids 需要删除的人员月度考核主键
     * @return 结果
     */
    @Override
    public int deletePersonnelMonthlyAssessmentByIds(Long[] ids) {
        return personnelMonthlyAssessmentMapper.deletePersonnelMonthlyAssessmentByIds(ids);
    }

    /**
     * 删除人员月度考核信息
     *
     * @param id 人员月度考核主键
     * @return 结果
     */
    @Override
    public int deletePersonnelMonthlyAssessmentById(Long id) {
        return personnelMonthlyAssessmentMapper.deletePersonnelMonthlyAssessmentById(id);
    }

    /**
     * 根据用户ID、年份和月份查询考核记录
     *
     * @param userId 用户ID
     * @param year   年份
     * @param month  月份
     * @return 人员月度考核
     */
    @Override
    public PersonnelMonthlyAssessment selectByUserIdAndYearMonth(Long userId, Integer year, Integer month) {
        return personnelMonthlyAssessmentMapper.selectByUserIdAndYearMonth(userId, year, month);
    }

    /**
     * 计算总分
     * 总分 = 100 - 红线扣分 - 违规排名扣分 - 技能排名扣分
     *
     * @param assessment 考核对象
     */
    private void calculateTotalScore(PersonnelMonthlyAssessment assessment) {
        int redLineDeduction = assessment.getRedLineDeduction() == null ? 0 : assessment.getRedLineDeduction();
        int violationRankingDeduction = assessment.getViolationRankingDeduction() == null ? 0 : assessment.getViolationRankingDeduction();
        int skillRankingDeduction = assessment.getSkillRankingDeduction() == null ? 0 : assessment.getSkillRankingDeduction();

        int totalScore = 100 - redLineDeduction - violationRankingDeduction - skillRankingDeduction;
        assessment.setTotalScore(totalScore);
    }

    /**
     * 过滤出需要生成本月考核的人员
     * 
     * @param managers 所有经理列表
     * @param year 年份
     * @param month 月份
     * @return 需要生成考核的经理列表
     */
    private List<PersonnelMonthlyAssessment> filterManagersForMonth(List<PersonnelMonthlyAssessment> managers, Integer year, Integer month) {
        List<PersonnelMonthlyAssessment> result = new ArrayList<>();
        
        // 计算本月的月初和月末日期
        java.util.Calendar calendar = java.util.Calendar.getInstance();
        calendar.set(year, month - 1, 1); // 月初（month-1因为Calendar的月份从0开始）
        java.util.Date monthStart = calendar.getTime();
        
        calendar.set(year, month - 1, calendar.getActualMaximum(java.util.Calendar.DAY_OF_MONTH)); // 月末
        java.util.Date monthEnd = calendar.getTime();
        
        for (PersonnelMonthlyAssessment manager : managers) {
            boolean shouldGenerate = false;
            
            if ("Y".equals(manager.getTakeAssessment())) {
                // 条件1：参加考核
                shouldGenerate = true;
            } else if ("N".equals(manager.getTakeAssessment())) {
                // 条件2：不参加考核，但需要检查免考核时间
                if (manager.getExemptTakeAssessmentStartTime() != null && manager.getExemptTakeAssessmentEndTime() != null) {
                    // 判断免考核时间是否包括整个月份
                    boolean exemptCoversWholeMonth = 
                        !manager.getExemptTakeAssessmentStartTime().after(monthStart) && 
                        !manager.getExemptTakeAssessmentEndTime().before(monthEnd);
                    
                    // 如果免考核时间不包括整个月份，则需要生成考核
                    if (!exemptCoversWholeMonth) {
                        shouldGenerate = true;
                    }
                }
            }
            
            if (shouldGenerate) {
                result.add(manager);
            }
        }
        
        return result;
    }

    /**
     * 获取经理/副经理的下属用户ID列表
     * 
     * @param managerUserId 经理/副经理用户ID
     * @param workArea 工作区域（副经理有值，经理为null或空）
     * @return 下属用户ID列表
     */
    private List<Long> getSubordinateUserIds(Long managerUserId, String workArea) {
        // 1. 查询经理/副经理的用户信息
        SysUser manager = sysUserMapper.selectUserById(managerUserId);
        if (manager == null || manager.getDeptId() == null) {
            return Collections.emptyList();
        }

        // 2. 获取该部门及所有子部门的ID列表
        List<Long> deptIds = getAllSubDeptIds(manager.getDeptId());

        // 3. 根据条件查询下属用户
        boolean isManager = (workArea == null || workArea.isEmpty());
        return personnelMonthlyAssessmentMapper.selectSubordinateUserIds(deptIds, workArea, isManager);
    }

    /**
     * 获取部门及所有子部门的ID列表
     * 
     * @param deptId 部门ID
     * @return 部门ID列表（包含当前部门及所有子部门）
     */
    private List<Long> getAllSubDeptIds(Long deptId) {
        List<Long> result = new ArrayList<>();
        result.add(deptId); // 添加当前部门

        // 查询所有子部门
        List<SysDept> subDepts = sysDeptMapper.selectChildrenDeptById(deptId);
        if (subDepts != null && !subDepts.isEmpty()) {
            for (SysDept subDept : subDepts) {
                if ("0".equals(subDept.getDelFlag())) { // 只包含未删除的部门
                    result.add(subDept.getDeptId());
                }
            }
        }

        return result;
    }

    /**
     * 生成本月考核数据
     *
     * @param year  年份
     * @param month 月份
     * @return 生成的记录数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int generateMonthlyAssessment(Integer year, Integer month) {
        // 1. 查询需要考核的经理/副经理列表
        List<PersonnelMonthlyAssessment> managers = personnelMonthlyAssessmentMapper.selectManagersForAssessment();
        if (managers == null || managers.isEmpty()) {
            throw new ServiceException("未找到需要考核的经理人员！");
        }

        // 2. 过滤出需要生成本月考核的人员
        List<PersonnelMonthlyAssessment> filteredManagers = filterManagersForMonth(managers, year, month);
        if (filteredManagers.isEmpty()) {
            throw new ServiceException("没有需要生成本月考核记录的人员！");
        }

        // 3. 检查是否已生成本月考核数据，收集需要更新的ID
        Map<Long, Long> existingRecordMap = new HashMap<>(); // userId -> 已存在的记录ID
        for (PersonnelMonthlyAssessment manager : filteredManagers) {
            PersonnelMonthlyAssessment existing = personnelMonthlyAssessmentMapper.selectByUserIdAndYearMonth(
                    manager.getUserId(), year, month);
            if (existing != null) {
                existingRecordMap.put(manager.getUserId(), existing.getId());
            }
        }

        // 4. 为每个经理收集下属用户ID
        Map<Long, List<Long>> managerSubordinatesMap = new HashMap<>();
        List<Long> allSubordinateIds = new ArrayList<>();
        for (PersonnelMonthlyAssessment manager : filteredManagers) {
            // 获取下属用户ID列表
            List<Long> subordinateIds = getSubordinateUserIds(manager.getUserId(), manager.getArea());
            managerSubordinatesMap.put(manager.getUserId(), subordinateIds);
            allSubordinateIds.addAll(subordinateIds);
        }

        // 5. 批量查询所有下属的红线行为次数
        Map<Long, Integer> redLineCountMap = batchQueryRedLineCounts(allSubordinateIds, year, month);

        // 6. 批量查询所有下属的SOC/品控扣分
        Map<Long, BigDecimal> socQcDeductionMap = batchQuerySocQcDeductions(allSubordinateIds, year, month);

        // 7. 批量查询所有下属的月考成绩
        Map<Long, List<Map<String, Object>>> examScoresMap = batchQueryExamScores(allSubordinateIds, year, month);

        // 8. 计算每个经理的各项扣分
        Map<Long, Integer> redLineDeductionMap = new HashMap<>();
        Map<Long, BigDecimal> teamDeductionMap = new HashMap<>();
        Map<Long, BigDecimal> teamPassRateMap = new HashMap<>();

        for (PersonnelMonthlyAssessment manager : filteredManagers) {
            Long managerId = manager.getUserId();
            List<Long> subordinateIds = managerSubordinatesMap.get(managerId);

            // 计算红线扣分
            int totalRedLineCount = 0;
            for (Long subId : subordinateIds) {
                totalRedLineCount += redLineCountMap.getOrDefault(subId, 0);
            }
            redLineDeductionMap.put(managerId, calculateRedLineDeduction(totalRedLineCount));

            // 判断是否为经理
            boolean isManager = (manager.getArea() == null || manager.getArea().isEmpty());
            
            if (isManager) {
                // 经理的扣分 = 所有下属副经理扣分*50% 的总和
                BigDecimal managerDeduction = calculateManagerDeduction(
                    manager, filteredManagers, managerSubordinatesMap, socQcDeductionMap
                );
                teamDeductionMap.put(managerId, managerDeduction);
            } else {
                // 副经理的扣分是其下属所有用户的扣分总和
                BigDecimal teamDeduction = BigDecimal.ZERO;
                for (Long subId : subordinateIds) {
                    teamDeduction = teamDeduction.add(socQcDeductionMap.getOrDefault(subId, BigDecimal.ZERO));
                }
                teamDeductionMap.put(managerId, teamDeduction);
            }

            // 计算团队通过率
            BigDecimal passRate = calculateTeamPassRate(subordinateIds, examScoresMap);
            teamPassRateMap.put(managerId, passRate);
        }

        // 8. 计算违规排名扣分（全局排序）
        Map<Long, Integer> violationDeductionMap = calculateViolationRankingDeduction(teamDeductionMap);

        // 9. 计算技能排名扣分（全局排序）
        Map<Long, Integer> skillDeductionMap = calculateSkillRankingDeduction(teamPassRateMap);

        // 10. 查询上月通过率用于豁免判断
        Map<Long, BigDecimal> lastMonthPassRateMap = batchQueryLastMonthPassRate(filteredManagers, year, month);

        // 11. 构建考核记录列表
        List<PersonnelMonthlyAssessment> insertList = new ArrayList<>();
        List<PersonnelMonthlyAssessment> updateList = new ArrayList<>();
        
        for (PersonnelMonthlyAssessment manager : filteredManagers) {
            PersonnelMonthlyAssessment assessment = new PersonnelMonthlyAssessment();
            assessment.setUserId(manager.getUserId());
            assessment.setName(manager.getName());
            assessment.setPost(manager.getPost());
            assessment.setArea(manager.getArea());
            assessment.setDeptId(manager.getDeptId());
            assessment.setDeptName(manager.getDeptName());
            assessment.setYear(year);
            assessment.setMonth(month);

            // 设置各项扣分
            assessment.setRedLineDeduction(redLineDeductionMap.getOrDefault(manager.getUserId(), 0));
            assessment.setViolationRankingDeduction(violationDeductionMap.getOrDefault(manager.getUserId(), 0));
            assessment.setSkillRankingDeduction(skillDeductionMap.getOrDefault(manager.getUserId(), 0));

            // 检查豁免情况
            BigDecimal currentPassRate = teamPassRateMap.get(manager.getUserId());
            BigDecimal lastPassRate = lastMonthPassRateMap.get(manager.getUserId());
            if (currentPassRate != null && lastPassRate != null 
                && currentPassRate.compareTo(BigDecimal.ZERO) > 0 
                && lastPassRate.compareTo(BigDecimal.ZERO) > 0
                && currentPassRate.compareTo(lastPassRate) > 0) {
                assessment.setSkillExemptionStatus("通过率较上月提升，豁免技能排名扣分");
                assessment.setSkillRankingDeduction(0);
            } else {
                assessment.setSkillExemptionStatus("无豁免");
            }

            // 计算总分
            calculateTotalScore(assessment);

            // 计算考核结果和备注
            calculateAssessmentResult(assessment);

            // 判断是新增还是更新
            Long existingId = existingRecordMap.get(manager.getUserId());
            if (existingId != null) {
                // 已存在，设置为更新
                assessment.setId(existingId);
                updateList.add(assessment);
            } else {
                // 不存在，设置为新增
                insertList.add(assessment);
            }
        }

        // 12. 批量插入和更新
        int insertCount = 0;
        int updateCount = 0;
        
        if (!insertList.isEmpty()) {
            insertCount = personnelMonthlyAssessmentMapper.batchInsertPersonnelMonthlyAssessment(insertList);
        }
        
        if (!updateList.isEmpty()) {
            for (PersonnelMonthlyAssessment assessment : updateList) {
                updateCount += personnelMonthlyAssessmentMapper.updatePersonnelMonthlyAssessment(assessment);
            }
        }

        return insertCount + updateCount;
    }

    /**
     * 计算红线扣分
     * 1次扣5分，2次扣10分，3次及以上扣20分
     *
     * @param redLineCount 红线行为次数
     * @return 扣分分值
     */
    private int calculateRedLineDeduction(int redLineCount) {
        if (redLineCount <= 0) {
            return 0;
        } else if (redLineCount == 1) {
            return 5;
        } else if (redLineCount == 2) {
            return 10;
        } else {
            return 20;
        }
    }

    /**
     * 批量查询红线行为次数
     */
    private Map<Long, Integer> batchQueryRedLineCounts(List<Long> userIds, Integer year, Integer month) {
        Map<Long, Integer> resultMap = new HashMap<>();
        if (userIds == null || userIds.isEmpty()) {
            return resultMap;
        }

        List<HashMap<String, Object>> results = personnelMonthlyAssessmentMapper.batchCountRedLineViolations(userIds, year, month);
        for (HashMap<String, Object> row : results) {
            Long userId = ((Number) row.get("userId")).longValue();
            Integer count = ((Number) row.get("redLineCount")).intValue();
            resultMap.put(userId, count);
        }
        return resultMap;
    }

    /**
     * 批量查询SOC/品控扣分
     */
    private Map<Long, BigDecimal> batchQuerySocQcDeductions(List<Long> userIds, Integer year, Integer month) {
        Map<Long, BigDecimal> resultMap = new HashMap<>();
        if (userIds == null || userIds.isEmpty()) {
            return resultMap;
        }

        List<HashMap<String, Object>> results = personnelMonthlyAssessmentMapper.batchGetSocQcDeductions(userIds, year, month);
        for (HashMap<String, Object> row : results) {
            Long userId = ((Number) row.get("userId")).longValue();
            BigDecimal deduction = new BigDecimal(row.get("totalDeduction").toString());
            resultMap.put(userId, deduction);
        }
        return resultMap;
    }

    /**
     * 批量查询月考成绩
     */
    private Map<Long, List<Map<String, Object>>> batchQueryExamScores(List<Long> userIds, Integer year, Integer month) {
        Map<Long, List<Map<String, Object>>> resultMap = new HashMap<>();
        if (userIds == null || userIds.isEmpty()) {
            return resultMap;
        }

        List<HashMap<String, Object>> results = personnelMonthlyAssessmentMapper.batchGetExamScores(userIds, year, month);
        for (HashMap<String, Object> row : results) {
            Long userId = ((Number) row.get("userId")).longValue();
            resultMap.computeIfAbsent(userId, k -> new ArrayList<>()).add(row);
        }
        return resultMap;
    }

    /**
     * 计算团队通过率
     */
    private BigDecimal calculateTeamPassRate(List<Long> subordinateIds, Map<Long, List<Map<String, Object>>> examScoresMap) {
        if (subordinateIds == null || subordinateIds.isEmpty()) {
            return BigDecimal.ZERO;
        }

        int totalCount = 0;
        int passCount = 0;

        for (Long userId : subordinateIds) {
            List<Map<String, Object>> scores = examScoresMap.get(userId);
            if (scores != null) {
                for (Map<String, Object> score : scores) {
                    totalCount++;
                    String post = (String) score.get("post");
                    BigDecimal scoreValue = new BigDecimal(score.get("score").toString());

                    // X光机操作员90分合格，四级安检员60分合格
                    if (("X光机操作员".equals(post) && scoreValue.compareTo(new BigDecimal("90")) >= 0)
                        || ("四级安检员".equals(post) && scoreValue.compareTo(new BigDecimal("60")) >= 0)) {
                        passCount++;
                    }
                }
            }
        }

        if (totalCount == 0) {
            return BigDecimal.ZERO;
        }

        return new BigDecimal(passCount).multiply(new BigDecimal("100")).divide(new BigDecimal(totalCount), 2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 批量查询上月通过率
     */
    private Map<Long, BigDecimal> batchQueryLastMonthPassRate(List<PersonnelMonthlyAssessment> managers, Integer year, Integer month) {
        Map<Long, BigDecimal> resultMap = new HashMap<>();

        // 计算上月的年月
        int lastYear = year;
        int lastMonth = month - 1;
        if (lastMonth == 0) {
            lastMonth = 12;
            lastYear = year - 1;
        }

        // 为每个经理查询上月通过率
        for (PersonnelMonthlyAssessment manager : managers) {
            List<Long> subordinateIds = getSubordinateUserIds(manager.getUserId(), manager.getArea());
            Map<Long, List<Map<String, Object>>> examScoresMap = batchQueryExamScores(subordinateIds, lastYear, lastMonth);
            BigDecimal passRate = calculateTeamPassRate(subordinateIds, examScoresMap);
            resultMap.put(manager.getUserId(), passRate);
        }

        return resultMap;
    }

    /**
     * 计算违规排名扣分
     * 扣分最多的扣3分，第二多扣2分，第三多扣1分
     *
     * @param teamDeductionMap 经理ID -> 团队扣分总额的映射
     * @return 经理ID -> 扣分的映射
     */
    private Map<Long, Integer> calculateViolationRankingDeduction(Map<Long, BigDecimal> teamDeductionMap) {
        Map<Long, Integer> deductionMap = new HashMap<>();

        if (teamDeductionMap == null || teamDeductionMap.isEmpty()) {
            return deductionMap;
        }

        // 按扣分总额从高到低排序，如果扣分相同则按经理ID从小到大排序
        List<Map.Entry<Long, BigDecimal>> sortedList = new ArrayList<>(teamDeductionMap.entrySet());
        sortedList.sort((e1, e2) -> e2.getValue().compareTo(e1.getValue()));

        int size = sortedList.size();
        if (size >= 3) {
            // 扣分最多的扣3分
            deductionMap.put(sortedList.get(0).getKey(), 3);
            // 扣分第二多的扣2分
            deductionMap.put(sortedList.get(1).getKey(), 2);
            // 扣分第三多的扣1分
            deductionMap.put(sortedList.get(2).getKey(), 1);
        } else if (size == 2) {
            deductionMap.put(sortedList.get(0).getKey(), 3);
            deductionMap.put(sortedList.get(1).getKey(), 2);
        } else if (size == 1) {
            deductionMap.put(sortedList.get(0).getKey(), 3);
        }

        return deductionMap;
    }

    /**
     * 计算技能排名扣分
     * 末位扣3分，倒数第二扣2分，倒数第三扣1分
     *
     * @param teamPassRateMap 经理ID -> 团队通过率的映射
     * @return 经理ID -> 扣分的映射
     */
    private Map<Long, Integer> calculateSkillRankingDeduction(Map<Long, BigDecimal> teamPassRateMap) {
        Map<Long, Integer> deductionMap = new HashMap<>();

        if (teamPassRateMap == null || teamPassRateMap.isEmpty()) {
            return deductionMap;
        }

        // 按通过率从低到高排序
        List<Map.Entry<Long, BigDecimal>> sortedList = new ArrayList<>(teamPassRateMap.entrySet());
        sortedList.sort((e1, e2) -> e1.getValue().compareTo(e2.getValue()));

        int size = sortedList.size();
        if (size >= 3) {
            // 末位（通过率最低）扣3分
            deductionMap.put(sortedList.get(0).getKey(), 3);
            // 倒数第二扣2分
            deductionMap.put(sortedList.get(1).getKey(), 2);
            // 倒数第三扣1分
            deductionMap.put(sortedList.get(2).getKey(), 1);
        } else if (size == 2) {
            deductionMap.put(sortedList.get(0).getKey(), 3);
            deductionMap.put(sortedList.get(1).getKey(), 2);
        } else if (size == 1) {
            deductionMap.put(sortedList.get(0).getKey(), 3);
        }

        return deductionMap;
    }

    /**
     * 计算考核结果和备注
     * 预警：得分低于90分
     * 待改进：得分低于85分
     * 不称职：得分低于80分
     *
     * @param assessment 考核对象
     */
    private void calculateAssessmentResult(PersonnelMonthlyAssessment assessment) {
        int totalScore = assessment.getTotalScore() == null ? 100 : assessment.getTotalScore();

        if (totalScore < 80) {
            assessment.setAssessmentResult("不称职");
            assessment.setAssessmentRemark("得分低于80分，认定不称职，建议调整岗位或降职处理");
            // 应用方式：降职降薪
            assessment.setApplicationMethod("降职降薪");
            assessment.setApplicationRemark("考核结果为不称职的，则进行降职降薪处理。");
        } else if (totalScore < 85) {
            assessment.setAssessmentResult("待改进");
            assessment.setAssessmentRemark("得分低于85分，认定待改进，同时启动干部任职画像民主测评");
            // 应用方式：民主测评
            assessment.setApplicationMethod("民主测评");
            assessment.setApplicationRemark("考核结果为待改进，启动干部任职画像民主测评，围绕专业能力、统筹协调能力、群众基础三个维度进行评价，据测评结果确定后续处置意见：");
        } else if (totalScore < 90) {
            assessment.setAssessmentResult("预警");
            assessment.setAssessmentRemark("得分低于90分，启动预警机制，由分管部门班子进行专项督导，推动管理提升");
            // 预警暂无特定应用方式
            assessment.setApplicationMethod(null);
            assessment.setApplicationRemark(null);
        } else {
            assessment.setAssessmentResult(null);
            assessment.setAssessmentRemark(null);
            assessment.setApplicationMethod(null);
            assessment.setApplicationRemark(null);
        }
    }

    /**
     * 计算经理的品控扣分
     * 规则：经理的扣分 = 所有下属副经理扣分*50% 的总和
     *
     * @param manager 经理对象
     * @param allManagers 所有经理/副经理列表
     * @param managerSubordinatesMap 经理ID -> 下属用户ID列表的映射
     * @param socQcDeductionMap 用户ID -> SOC/品控扣分的映射
     * @return 经理的品控扣分
     */
    private BigDecimal calculateManagerDeduction(
            PersonnelMonthlyAssessment manager,
            List<PersonnelMonthlyAssessment> allManagers,
            Map<Long, List<Long>> managerSubordinatesMap,
            Map<Long, BigDecimal> socQcDeductionMap) {
        
        // 1. 找出该经理下属的所有副经理（同一部门且有workArea）
        List<PersonnelMonthlyAssessment> viceManagersUnderManager = allManagers.stream()
            .filter(m -> m.getArea() != null && !m.getArea().isEmpty()) // 是副经理
            .filter(m -> {
                // 判断副经理是否属于该经理的部门
                SysUser viceManager = sysUserMapper.selectUserById(m.getUserId());
                return viceManager != null && viceManager.getDeptId() != null 
                    && viceManager.getDeptId().equals(manager.getDeptId());
            })
            .collect(Collectors.toList());

        // 2. 计算每个副经理的扣分*50%，然后累加
        BigDecimal managerTotalDeduction = BigDecimal.ZERO;
        for (PersonnelMonthlyAssessment viceManager : viceManagersUnderManager) {
            // 获取该副经理的下属用户ID列表
            List<Long> viceManagerSubIds = managerSubordinatesMap.get(viceManager.getUserId());
            
            // 累加该副经理下属的所有扣分
            BigDecimal viceManagerTotalDeduction = BigDecimal.ZERO;
            for (Long subId : viceManagerSubIds) {
                viceManagerTotalDeduction = viceManagerTotalDeduction.add(
                    socQcDeductionMap.getOrDefault(subId, BigDecimal.ZERO)
                );
            }
            
            // 该副经理的扣分 * 50%
            viceManagerTotalDeduction = viceManagerTotalDeduction.multiply(new BigDecimal("0.5"));
            
            // 累加到经理的总扣分
            managerTotalDeduction = managerTotalDeduction.add(viceManagerTotalDeduction);
        }
        
        return managerTotalDeduction;
    }
}
