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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sundot.airport.common.core.domain.entity.SysDept;
import com.sundot.airport.common.exception.ServiceException;
import com.sundot.airport.exam.domain.DailyTask;
import com.sundot.airport.exam.domain.DailyTaskDetail;
import com.sundot.airport.exam.domain.QuesCat;
import com.sundot.airport.exam.dto.DeptProfileDTO;
import com.sundot.airport.exam.dto.DeptProfileQueryDTO;
import com.sundot.airport.exam.mapper.DailyTaskDetailMapper;
import com.sundot.airport.exam.mapper.DailyTaskMapper;
import com.sundot.airport.exam.service.IDeptProfileService;
import com.sundot.airport.exam.common.service.QuesCatService;
import com.sundot.airport.system.service.ISysDeptService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Date;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <b>功能名：</b>DeptProfileServiceImpl<br>
 * <b>说明：</b> 组织画像Service实现 <br>
 * <b>著作权：</b> Copyright (C) 2025 SUNDOT CORPORATION<br>
 * <b>修改履历：
 *
 * @author Claude
 */
@Service
public class DeptProfileServiceImpl implements IDeptProfileService {

    private static final Logger log = LoggerFactory.getLogger(DeptProfileServiceImpl.class);

    @Autowired
    private DailyTaskMapper dailyTaskMapper;

    @Autowired
    private DailyTaskDetailMapper dailyTaskDetailMapper;

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private QuesCatService quesCatService;

    @Autowired
    private com.sundot.airport.system.service.IBaseCheckCategoryService baseCheckCategoryService;

    @Override
    public DeptProfileDTO getDeptProfile(DeptProfileQueryDTO query) {
        log.info("获取组织画像 - deptId: {}, startDate: {}, endDate: {}",
                query.getDeptId(), query.getStartDate(), query.getEndDate());

        // 1. 参数校验
        validateQuery(query);

        // 2. 获取部门信息
        SysDept dept = deptService.selectDeptById(query.getDeptId());
        if (dept == null) {
            throw new ServiceException("部门不存在: deptId=" + query.getDeptId());
        }

        // 3. 解析部门层级
        DeptHierarchy hierarchy = parseDeptHierarchy(dept);

        // 4. 构建组织画像DTO
        DeptProfileDTO profile = new DeptProfileDTO();
        profile.setDeptId(dept.getDeptId());
        profile.setDeptName(dept.getDeptName());
        profile.setDeptType(hierarchy.deptType);
        profile.setPeriod(query.getStartDate() + " ~ " + query.getEndDate());

        // 5. 计算组织平均分
        profile.setAvgScore(calculateDeptAvgScore(query));

        // 6. 计算排名
        profile.setRankingStats(calculateRankingStatistics(query, dept, hierarchy));

        // 7. 计算总错题数量
        profile.setTotalErrors(calculateTotalErrors(query));

        // 8. 计算各分类错题数量
        profile.setCategoryErrors(calculateCategoryErrors(query));

        return profile;
    }

    /**
     * 参数校验
     */
    private void validateQuery(DeptProfileQueryDTO query) {
        if (query.getDeptId() == null) {
            throw new ServiceException("部门ID不能为空");
        }
        if (query.getStartDate() == null || query.getStartDate().trim().isEmpty()) {
            throw new ServiceException("开始日期不能为空");
        }
        if (query.getEndDate() == null || query.getEndDate().trim().isEmpty()) {
            throw new ServiceException("结束日期不能为空");
        }
    }

    /**
     * 计算组织平均分
     */
    private BigDecimal calculateDeptAvgScore(DeptProfileQueryDTO query) {
        // 获取当前部门信息
        SysDept dept = deptService.selectDeptById(query.getDeptId());
        DeptHierarchy hierarchy = parseDeptHierarchy(dept);

        // 获取需要查询的部门ID列表
        List<Long> deptIds = getQueryDeptIds(query.getDeptId(), hierarchy);

        // 查询这些部门所有用户在周期内的任务（COMPLETED和EXPIRED）
        LambdaQueryWrapper<DailyTask> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(DailyTask::getDtDeptId, deptIds);
        wrapper.ge(DailyTask::getDtBusinessDate, Date.valueOf(query.getStartDate()));
        wrapper.le(DailyTask::getDtBusinessDate, Date.valueOf(query.getEndDate()));
        wrapper.in(DailyTask::getDtStatus, "COMPLETED", "EXPIRED");
        wrapper.eq(DailyTask::getDelStatus, 0);
        List<DailyTask> tasks = dailyTaskMapper.selectList(wrapper);

        if (tasks.isEmpty()) {
            return BigDecimal.ZERO;
        }

        // 计算平均分（EXPIRED任务分数算0）
        BigDecimal totalScore = tasks.stream()
                .map(task -> "EXPIRED".equals(task.getDtStatus()) ? BigDecimal.ZERO : task.getDtTotalScore())
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        return totalScore.divide(new BigDecimal(tasks.size()), 2, RoundingMode.HALF_UP);
    }

    /**
     * 获取需要查询的部门ID列表
     * 如果是班组：返回班组ID本身
     * 如果是科室：返回该科室下所有班组ID
     * 如果是站级：返回该站级下所有班组ID
     */
    private List<Long> getQueryDeptIds(Long deptId, DeptHierarchy hierarchy) {
        List<Long> deptIds = new ArrayList<>();

        if ("TEAM".equals(hierarchy.deptType)) {
            // 班组：直接返回班组ID
            deptIds.add(deptId);
        } else if ("DEPT".equals(hierarchy.deptType)) {
            // 科室：查询该科室下所有班组
            List<SysDept> allDepts = deptService.selectDeptInfoAll(new SysDept());
            for (SysDept dept : allDepts) {
                if ("0".equals(dept.getDelFlag())) {
                    DeptHierarchy h = parseDeptHierarchy(dept);
                    // 筛选该科室下的所有班组
                    if ("TEAM".equals(h.deptType) && deptId.equals(h.deptId)) {
                        deptIds.add(dept.getDeptId());
                    }
                }
            }
        } else if ("SITE".equals(hierarchy.deptType)) {
            // 站级：查询该站级下所有班组
            List<SysDept> allDepts = deptService.selectDeptInfoAll(new SysDept());
            for (SysDept dept : allDepts) {
                if ("0".equals(dept.getDelFlag())) {
                    DeptHierarchy h = parseDeptHierarchy(dept);
                    // 筛选该站级下的所有班组
                    if ("TEAM".equals(h.deptType) && deptId.equals(h.siteId)) {
                        deptIds.add(dept.getDeptId());
                    }
                }
            }
        }

        // 如果没有找到任何班组，至少返回当前部门ID（避免空列表导致SQL错误）
        if (deptIds.isEmpty()) {
            deptIds.add(deptId);
        }

        return deptIds;
    }

    /**
     * 计算排名统计
     */
    private DeptProfileDTO.RankingStatistics calculateRankingStatistics(
            DeptProfileQueryDTO query, SysDept dept, DeptHierarchy hierarchy) {

        DeptProfileDTO.RankingStatistics stats = new DeptProfileDTO.RankingStatistics();

        // 计算所有部门的平均分
        Map<Long, BigDecimal> deptAvgScoreMap = calculateAllDeptAvgScores(query);

        // 获取当前部门的平均分
        BigDecimal deptAvgScore = deptAvgScoreMap.getOrDefault(query.getDeptId(), BigDecimal.ZERO);

        if ("TEAM".equals(hierarchy.deptType)) {
            // 班组级别：需要计算全站排名和本科室排名

            // 1. 全站排名（相同站级下的所有班组）
            Map<Long, BigDecimal> siteTeamScores = getAllSameLevelDeptScores(hierarchy, deptAvgScoreMap);

            stats.setSiteRanking(calculateRanking(deptAvgScore, siteTeamScores.values()));
            stats.setSiteTotalDepts(siteTeamScores.size());

            // 2. 本科室排名（相同科级下的所有班组）
            Map<Long, BigDecimal> deptTeamScores = getAllSameDeptTeamScores(hierarchy, deptAvgScoreMap);

            stats.setDeptRanking(calculateRanking(deptAvgScore, deptTeamScores.values()));
            stats.setDeptTotalTeams(deptTeamScores.size());

        } else if ("DEPT".equals(hierarchy.deptType)) {
            // 科室级别：只需要计算全站排名（相同站级下的所有科室）

            // 查询所有同级科室（包括没有任务数据的）
            Map<Long, BigDecimal> siteDeptScores = getAllSameLevelDeptScores(hierarchy, deptAvgScoreMap);

            stats.setSiteRanking(calculateRanking(deptAvgScore, siteDeptScores.values()));
            stats.setSiteTotalDepts(siteDeptScores.size());

            // 科室级别没有本科室排名
            stats.setDeptRanking(null);
            stats.setDeptTotalTeams(null);
        }

        return stats;
    }

    /**
     * 获取所有同级部门的分数（只统计有任务数据的部门）
     * 用于全站排名
     */
    private Map<Long, BigDecimal> getAllSameLevelDeptScores(DeptHierarchy hierarchy, Map<Long, BigDecimal> deptAvgScoreMap) {
        Map<Long, BigDecimal> result = new HashMap<>();

        // 查询所有正常状态的部门
        List<SysDept> allDepts = deptService.selectDeptInfoAll(new SysDept());

        // 筛选出同级部门（只保留有任务数据的）
        for (SysDept dept : allDepts) {
            if ("0".equals(dept.getDelFlag())) {
                DeptHierarchy h = parseDeptHierarchy(dept);

                if ("DEPT".equals(hierarchy.deptType)) {
                    // 科室级别：筛选相同站级的所有科室
                    if ("DEPT".equals(h.deptType) && hierarchy.siteId.equals(h.siteId)) {
                        // 只统计有任务数据的科室
                        if (deptAvgScoreMap.containsKey(dept.getDeptId())) {
                            result.put(dept.getDeptId(), deptAvgScoreMap.get(dept.getDeptId()));
                        }
                    }
                } else if ("TEAM".equals(hierarchy.deptType)) {
                    // 班组级别：筛选相同站级的所有班组
                    if ("TEAM".equals(h.deptType) && hierarchy.siteId.equals(h.siteId)) {
                        // 只统计有任务数据的班组
                        if (deptAvgScoreMap.containsKey(dept.getDeptId())) {
                            result.put(dept.getDeptId(), deptAvgScoreMap.get(dept.getDeptId()));
                        }
                    }
                }
            }
        }

        return result;
    }

    /**
     * 获取本科室所有班组的分数（只统计有任务数据的班组）
     * 用于本科室排名
     */
    private Map<Long, BigDecimal> getAllSameDeptTeamScores(DeptHierarchy hierarchy, Map<Long, BigDecimal> deptAvgScoreMap) {
        Map<Long, BigDecimal> result = new HashMap<>();

        // 查询所有正常状态的部门
        List<SysDept> allDepts = deptService.selectDeptInfoAll(new SysDept());

        // 筛选出同一科级的所有班组（只保留有任务数据的）
        for (SysDept dept : allDepts) {
            if ("0".equals(dept.getDelFlag())) {
                DeptHierarchy h = parseDeptHierarchy(dept);

                // 筛选相同科级的所有班组
                if ("TEAM".equals(h.deptType) && hierarchy.deptId.equals(h.deptId)) {
                    // 只统计有任务数据的班组
                    if (deptAvgScoreMap.containsKey(dept.getDeptId())) {
                        result.put(dept.getDeptId(), deptAvgScoreMap.get(dept.getDeptId()));
                    }
                }
            }
        }

        return result;
    }

    /**
     * 计算排名
     */
    private Integer calculateRanking(BigDecimal score, Collection<BigDecimal> allScores) {
        List<BigDecimal> sortedScores = new ArrayList<>(allScores);
        sortedScores.sort(Comparator.reverseOrder());

        int ranking = 1;
        for (BigDecimal s : sortedScores) {
            if (s.compareTo(score) > 0) {
                ranking++;
            } else {
                break;
            }
        }
        return ranking;
    }

    /**
     * 计算所有部门的平均分
     * 注意：edu_cs_daily_task.dt_dept_id 只存储班组ID
     * 所以需要将班组的分数汇总到科室和站级
     */
    private Map<Long, BigDecimal> calculateAllDeptAvgScores(DeptProfileQueryDTO query) {
        // 查询周期内所有已完成和已过期的任务
        LambdaQueryWrapper<DailyTask> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(DailyTask::getDtBusinessDate, Date.valueOf(query.getStartDate()));
        wrapper.le(DailyTask::getDtBusinessDate, Date.valueOf(query.getEndDate()));
        wrapper.in(DailyTask::getDtStatus, "COMPLETED", "EXPIRED");
        wrapper.eq(DailyTask::getDelStatus, 0);
        List<DailyTask> allTasks = dailyTaskMapper.selectList(wrapper);

        // 按班组分组计算平均分（dt_dept_id存储的是班组ID）
        Map<Long, List<DailyTask>> teamTasksMap = allTasks.stream()
                .collect(Collectors.groupingBy(DailyTask::getDtDeptId));

        Map<Long, BigDecimal> deptAvgScoreMap = new HashMap<>();

        // 1. 先计算每个班组的平均分
        for (Map.Entry<Long, List<DailyTask>> entry : teamTasksMap.entrySet()) {
            List<DailyTask> tasks = entry.getValue();
            if (!tasks.isEmpty()) {
                BigDecimal totalScore = tasks.stream()
                        .map(task -> "EXPIRED".equals(task.getDtStatus()) ? BigDecimal.ZERO : task.getDtTotalScore())
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal avgScore = totalScore.divide(new BigDecimal(tasks.size()), 2, RoundingMode.HALF_UP);
                deptAvgScoreMap.put(entry.getKey(), avgScore);
            }
        }

        // 2. 计算每个科室和站级的平均分（汇总下属班组的任务）
        List<SysDept> allDepts = deptService.selectDeptInfoAll(new SysDept());
        for (SysDept dept : allDepts) {
            if ("0".equals(dept.getDelFlag())) {
                DeptHierarchy h = parseDeptHierarchy(dept);

                // 只处理科室和站级（班组的分数已经在上面计算过了）
                if ("DEPT".equals(h.deptType) || "SITE".equals(h.deptType)) {
                    // 找出该部门下所有班组的任务
                    List<Long> subTeamIds = getQueryDeptIds(dept.getDeptId(), h);

                    // 汇总这些班组的所有任务
                    List<DailyTask> deptTasks = new ArrayList<>();
                    for (Long teamId : subTeamIds) {
                        List<DailyTask> tasks = teamTasksMap.get(teamId);
                        if (tasks != null) {
                            deptTasks.addAll(tasks);
                        }
                    }

                    // 计算该科室/站级的平均分
                    if (!deptTasks.isEmpty()) {
                        BigDecimal totalScore = deptTasks.stream()
                                .map(task -> "EXPIRED".equals(task.getDtStatus()) ? BigDecimal.ZERO : task.getDtTotalScore())
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                        BigDecimal avgScore = totalScore.divide(new BigDecimal(deptTasks.size()), 2, RoundingMode.HALF_UP);
                        deptAvgScoreMap.put(dept.getDeptId(), avgScore);
                    }
                }
            }
        }

        return deptAvgScoreMap;
    }

    /**
     * 计算总错题数量
     */
    private Integer calculateTotalErrors(DeptProfileQueryDTO query) {
        // 获取当前部门信息
        SysDept dept = deptService.selectDeptById(query.getDeptId());
        DeptHierarchy hierarchy = parseDeptHierarchy(dept);

        // 获取需要查询的部门ID列表
        List<Long> deptIds = getQueryDeptIds(query.getDeptId(), hierarchy);

        // 查询这些部门所有用户在周期内的任务（COMPLETED和EXPIRED）
        LambdaQueryWrapper<DailyTask> taskWrapper = new LambdaQueryWrapper<>();
        taskWrapper.in(DailyTask::getDtDeptId, deptIds);
        taskWrapper.ge(DailyTask::getDtBusinessDate, Date.valueOf(query.getStartDate()));
        taskWrapper.le(DailyTask::getDtBusinessDate, Date.valueOf(query.getEndDate()));
        taskWrapper.in(DailyTask::getDtStatus, "COMPLETED", "EXPIRED");
        taskWrapper.eq(DailyTask::getDelStatus, 0);
        List<DailyTask> tasks = dailyTaskMapper.selectList(taskWrapper);

        if (tasks.isEmpty()) {
            return 0;
        }

        int totalErrors = 0;

        for (DailyTask task : tasks) {
            if ("EXPIRED".equals(task.getDtStatus())) {
                // EXPIRED任务：所有题目都算错题
                LambdaQueryWrapper<DailyTaskDetail> allWrapper = new LambdaQueryWrapper<>();
                allWrapper.eq(DailyTaskDetail::getDtdTaskId, task.getDtId());
                allWrapper.eq(DailyTaskDetail::getDelStatus, 0);
                totalErrors += dailyTaskDetailMapper.selectCount(allWrapper).intValue();
            } else {
                // COMPLETED任务：只统计错题
                LambdaQueryWrapper<DailyTaskDetail> errorWrapper = new LambdaQueryWrapper<>();
                errorWrapper.eq(DailyTaskDetail::getDtdTaskId, task.getDtId());
                errorWrapper.eq(DailyTaskDetail::getDtdIsCorrect, false);
                errorWrapper.eq(DailyTaskDetail::getDelStatus, 0);
                totalErrors += dailyTaskDetailMapper.selectCount(errorWrapper).intValue();
            }
        }

        return totalErrors;
    }

    /**
     * 计算各分类错题数量（按一级分类）
     */
    private List<DeptProfileDTO.CategoryErrorStatistics> calculateCategoryErrors(DeptProfileQueryDTO query) {
        List<DeptProfileDTO.CategoryErrorStatistics> categoryErrorsList = new ArrayList<>();

        // 获取当前部门信息
        SysDept dept = deptService.selectDeptById(query.getDeptId());
        DeptHierarchy hierarchy = parseDeptHierarchy(dept);

        // 获取需要查询的部门ID列表
        List<Long> deptIds = getQueryDeptIds(query.getDeptId(), hierarchy);

        // 查询这些部门所有用户在周期内的任务（COMPLETED和EXPIRED）
        LambdaQueryWrapper<DailyTask> taskWrapper = new LambdaQueryWrapper<>();
        taskWrapper.in(DailyTask::getDtDeptId, deptIds);
        taskWrapper.ge(DailyTask::getDtBusinessDate, Date.valueOf(query.getStartDate()));
        taskWrapper.le(DailyTask::getDtBusinessDate, Date.valueOf(query.getEndDate()));
        taskWrapper.in(DailyTask::getDtStatus, "COMPLETED", "EXPIRED");
        taskWrapper.eq(DailyTask::getDelStatus, 0);
        List<DailyTask> tasks = dailyTaskMapper.selectList(taskWrapper);

        if (tasks.isEmpty()) {
            return categoryErrorsList;
        }

        // 分别处理COMPLETED和EXPIRED任务
        List<DailyTaskDetail> errorDetails = new ArrayList<>();

        for (DailyTask task : tasks) {
            if ("EXPIRED".equals(task.getDtStatus())) {
                // EXPIRED任务：所有题目都算错题
                LambdaQueryWrapper<DailyTaskDetail> allWrapper = new LambdaQueryWrapper<>();
                allWrapper.eq(DailyTaskDetail::getDtdTaskId, task.getDtId());
                allWrapper.eq(DailyTaskDetail::getDelStatus, 0);
                errorDetails.addAll(dailyTaskDetailMapper.selectList(allWrapper));
            } else {
                // COMPLETED任务：只统计错题
                LambdaQueryWrapper<DailyTaskDetail> errorWrapper = new LambdaQueryWrapper<>();
                errorWrapper.eq(DailyTaskDetail::getDtdTaskId, task.getDtId());
                errorWrapper.eq(DailyTaskDetail::getDtdIsCorrect, false);
                errorWrapper.eq(DailyTaskDetail::getDelStatus, 0);
                errorDetails.addAll(dailyTaskDetailMapper.selectList(errorWrapper));
            }
        }

        if (errorDetails.isEmpty()) {
            return categoryErrorsList;
        }

        // 按一级分类分组统计错题
        Map<String, Integer> level1CategoryErrorCounts = groupErrorsByLevel1Category(errorDetails);

        // 获取所有一级分类
        com.sundot.airport.system.domain.BaseCheckCategory queryParam = new com.sundot.airport.system.domain.BaseCheckCategory();
        queryParam.setLevel(1);
        List<com.sundot.airport.system.domain.BaseCheckCategory> level1Categories =
                baseCheckCategoryService.selectBaseCheckCategoryList(queryParam);

        // 构建分类错题统计列表
        for (com.sundot.airport.system.domain.BaseCheckCategory level1Category : level1Categories) {
            String categoryId = String.valueOf(level1Category.getId());
            Integer errorCount = level1CategoryErrorCounts.getOrDefault(categoryId, 0);

            // 只添加有错题的分类
            if (errorCount > 0) {
                DeptProfileDTO.CategoryErrorStatistics stats = new DeptProfileDTO.CategoryErrorStatistics();
                stats.setCategoryId(categoryId);
                stats.setCategoryName(level1Category.getName());
                stats.setErrorCount(errorCount);
                categoryErrorsList.add(stats);
            }
        }

        // 处理"未分类"的错题
        Integer uncategorizedCount = level1CategoryErrorCounts.getOrDefault(null, 0);
        if (uncategorizedCount > 0) {
            DeptProfileDTO.CategoryErrorStatistics uncategorized = new DeptProfileDTO.CategoryErrorStatistics();
            uncategorized.setCategoryId(null);
            uncategorized.setCategoryName("未分类");
            uncategorized.setErrorCount(uncategorizedCount);
            categoryErrorsList.add(uncategorized);
        }

        // 按错题数量降序排序
        categoryErrorsList.sort((a, b) -> b.getErrorCount().compareTo(a.getErrorCount()));

        return categoryErrorsList;
    }

    /**
     * 解析部门层级
     */
    private DeptHierarchy parseDeptHierarchy(SysDept dept) {
        DeptHierarchy hierarchy = new DeptHierarchy();

        String ancestors = dept.getAncestors();
        Long deptId = dept.getDeptId();

        if (ancestors == null || ancestors.trim().isEmpty()) {
            // 没有ancestors，当前dept_id可能是站级
            hierarchy.siteId = deptId;
            hierarchy.deptId = deptId;
            hierarchy.teamId = deptId;
            hierarchy.deptType = "SITE";
            return hierarchy;
        }

        // 分割ancestors：0,211,205
        String[] ancestorIds = ancestors.split(",");

        // ancestors[0] = 0 (root)
        // ancestors[1] = 站级ID
        // ancestors[2] = 科级ID
        // dept_id = 班组ID（如果有3层以上）

        if (ancestorIds.length >= 2) {
            hierarchy.siteId = Long.parseLong(ancestorIds[1].trim());
        }

        if (ancestorIds.length >= 3) {
            hierarchy.deptId = Long.parseLong(ancestorIds[2].trim());
        }

        // 判断部门类型
        if (ancestorIds.length == 1) {
            // ancestors = "0"，dept_id是站级
            hierarchy.siteId = deptId;
            hierarchy.deptId = deptId;
            hierarchy.teamId = deptId;
            hierarchy.deptType = "SITE";
        } else if (ancestorIds.length == 2) {
            // ancestors = "0,211"，dept_id是科级
            hierarchy.deptId = deptId;
            hierarchy.teamId = deptId;
            hierarchy.deptType = "DEPT";
        } else if (ancestorIds.length >= 3) {
            // ancestors = "0,211,205"，dept_id是班组
            hierarchy.teamId = deptId;
            hierarchy.deptType = "TEAM";
        }

        return hierarchy;
    }

    /**
     * 部门层级内部类
     */
    private static class DeptHierarchy {
        Long siteId;      // 站级ID
        Long deptId;      // 科级ID
        Long teamId;      // 班组ID
        String deptType;  // 部门类型：SITE/DEPT/TEAM
    }

    /**
     * 按一级分类分组统计错题数量
     * <p>
     * 1. 从DailyTaskDetail中获取二级分类ID（dtdModuleId，即qc_id）
     * 2. 通过qc_id查询edu_cs_ques_cat获取二级分类名称（qc_name）
     * 3. 通过qc_name在base_check_category中查找对应的一级分类
     * 4. 按一级分类ID分组统计
     * 5. 如果找不到对应的一级分类，则归入null（未分类）
     * </p>
     *
     * @param errorDetails 错题明细列表
     * @return 一级分类ID -> 错题数量的Map，key为null表示未分类
     */
    private Map<String, Integer> groupErrorsByLevel1Category(List<DailyTaskDetail> errorDetails) {
        Map<String, Integer> result = new HashMap<>();

        // 缓存二级分类名称到一级分类ID的映射
        Map<String, String> level2NameToLevel1IdCache = new HashMap<>();

        for (DailyTaskDetail detail : errorDetails) {
            String qcId = detail.getDtdModuleId(); // 二级分类ID（edu_cs_ques_cat.qc_id）

            if (qcId == null || qcId.trim().isEmpty()) {
                // 未分类
                result.put(null, result.getOrDefault(null, 0) + 1);
                continue;
            }

            // 查询二级分类名称
            LambdaQueryWrapper<QuesCat> catWrapper = new LambdaQueryWrapper<>();
            catWrapper.eq(QuesCat::getQcId, qcId);
            catWrapper.eq(QuesCat::getDelStatus, 0);
            QuesCat quesCat = quesCatService.getOne(catWrapper);

            if (quesCat == null || quesCat.getQcName() == null) {
                // 找不到二级分类，归入未分类
                result.put(null, result.getOrDefault(null, 0) + 1);
                continue;
            }

            String qcName = quesCat.getQcName();

            // 检查缓存
            String level1CategoryId;
            if (level2NameToLevel1IdCache.containsKey(qcName)) {
                level1CategoryId = level2NameToLevel1IdCache.get(qcName);
            } else {
                // 通过二级分类名称查找对应的一级分类
                com.sundot.airport.system.domain.BaseCheckCategory level1Category =
                        baseCheckCategoryService.selectLevel1ByLevel2Name(qcName);

                if (level1Category != null) {
                    level1CategoryId = String.valueOf(level1Category.getId());
                    level2NameToLevel1IdCache.put(qcName, level1CategoryId);
                } else {
                    // 找不到一级分类，归入未分类
                    level1CategoryId = null;
                    level2NameToLevel1IdCache.put(qcName, null);
                }
            }

            // 按一级分类ID统计
            result.put(level1CategoryId, result.getOrDefault(level1CategoryId, 0) + 1);
        }

        return result;
    }
}
