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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.sundot.airport.common.core.domain.BaseLargeScreenQueryParamDto;
import com.sundot.airport.common.core.domain.BoxPlotDataDto;
import com.sundot.airport.common.core.domain.GroupedBoxPlotDataDto;
import com.sundot.airport.common.core.domain.LargeScreenHomePageUserInfoSqlDto;
import com.sundot.airport.common.core.domain.SysUsageReportDto;
import com.sundot.airport.common.core.domain.SysUsageReportSeizureDto;
import com.sundot.airport.common.core.domain.entity.SysDept;
import com.sundot.airport.common.core.domain.entity.SysUser;
import com.sundot.airport.common.dto.BaseCommonDto;
import com.sundot.airport.item.domain.*;
import com.sundot.airport.item.mapper.ItemLargeScreenMapper;
import com.sundot.airport.item.mapper.SeizureReportMapper;
import com.sundot.airport.item.service.ItemLargeScreenService;
import com.sundot.airport.item.service.SeizureDistributionService;
import com.sundot.airport.system.service.ISysDeptService;
import com.sundot.airport.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 查获大屏Service业务层处理
 *
 * @author ruoyi
 * @date 2025-07-10
 */
@Service
public class ItemLargeScreenServiceImpl implements ItemLargeScreenService {

    @Autowired
    private ItemLargeScreenMapper itemLargeScreenMapper;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private SeizureDistributionService seizureDistributionService;
    @Autowired
    private SeizureReportMapper seizureReportMapper;
    @Autowired
    private ISysDeptService sysDeptService;

    /**
     * 移交公安情况
     *
     * @param dto 大屏查询参数
     * @return 移交公安情况
     */
    @Override
    public List<ItemLargeScreenInfoDto> police(BaseLargeScreenQueryParamDto dto) {
        return itemLargeScreenMapper.police(dto);
    }

    /**
     * 故意隐匿情况
     *
     * @param dto 大屏查询参数
     * @return 故意隐匿情况
     */
    @Override
    public List<ItemLargeScreenInfoDto> conceal(BaseLargeScreenQueryParamDto dto) {
        return itemLargeScreenMapper.conceal(dto);
    }

    /**
     * 查获类别分布
     *
     * @param dto 大屏查询参数
     * @return 查获类别分布
     */
    @Override
    public List<ItemLargeScreenCommonDto> category(BaseLargeScreenQueryParamDto dto) {
        BigDecimal totalSum = itemLargeScreenMapper.getTotalSum(dto);
        if (totalSum.compareTo(BigDecimal.ZERO) == 0) {
            return Collections.emptyList();
        }
        List<ItemLargeScreenCommonDto> result = itemLargeScreenMapper.category(dto);
        result.forEach(item -> item.setScale(item.getTotal().multiply(new BigDecimal("100")).divide(totalSum, 2, BigDecimal.ROUND_HALF_UP)));
        return result;
    }

    /**
     * 查获岗位分布
     *
     * @param dto 大屏查询参数
     * @return 查获岗位分布
     */
    @Override
    public List<ItemLargeScreenCommonDto> post(BaseLargeScreenQueryParamDto dto) {
        BigDecimal totalSum = itemLargeScreenMapper.getTotalSum(dto);
        if (totalSum.compareTo(BigDecimal.ZERO) == 0) {
            return Collections.emptyList();
        }
        List<ItemLargeScreenCommonDto> result = itemLargeScreenMapper.post(dto);
        result.forEach(item -> item.setScale(item.getTotal().multiply(new BigDecimal("100")).divide(totalSum, 2, BigDecimal.ROUND_HALF_UP)));
        return result;
    }

    /**
     * 查获总数量+移交公安数量+故意隐匿数量
     *
     * @param dto 大屏查询参数
     * @return 查获总数量+移交公安数量+故意隐匿数量
     */
    @Override
    public ItemLargeScreenTotalSomeDto getTotalSome(BaseLargeScreenQueryParamDto dto) {
        if (dto.getSpecifiedDate() == null) {
            dto.setSpecifiedDate(Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant()));
        }
        ItemLargeScreenTotalSomeDto result = itemLargeScreenMapper.getTotalSome(dto);

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dto.getSpecifiedDate());
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        Date previousDate = calendar.getTime();
        dto.setSpecifiedDate(previousDate);
        ItemLargeScreenTotalSomeDto before = itemLargeScreenMapper.getTotalSome(dto);
        result.setTotalBefore(before.getTotal());
        result.setPoliceTotalBefore(before.getPoliceTotal());
        result.setConcealTotalBefore(before.getConcealTotal());
        return result;
    }

    /**
     * app端查获总数量+移交公安数量+故意隐匿数量
     *
     * @param dto 大屏查询参数
     * @return
     */
    @Override
    public ItemLargeScreenTotalSomeDto getAppTotalSome(BaseLargeScreenQueryParamDto dto) {
        return itemLargeScreenMapper.getTotalSome(dto);
    }

    /**
     * pc端查获总数量+移交公安数量+故意隐匿数量(不需要完成审核)
     *
     * @param dto 大屏查询参数
     * @return 查获总数量+移交公安数量+故意隐匿数量
     */
    @Override
    public ItemLargeScreenTotalSomeDto getPcTotalSome(BaseLargeScreenQueryParamDto dto) {
        return itemLargeScreenMapper.getPcTotalSome(dto);
    }

    /**
     * 查获排名
     *
     * @param dto  大屏查询参数
     * @param type 类型:1=按科室;2=按班组;3=按个人;4=按大队
     * @return 查获排名
     */
    @Override
    public List<ItemLargeScreenCommonDto> rank(BaseLargeScreenQueryParamDto dto, int type) {
        BigDecimal totalSum = itemLargeScreenMapper.getTotalSum(dto);
        if (totalSum.compareTo(BigDecimal.ZERO) == 0) {
            return Collections.emptyList();
        }
        List<ItemLargeScreenCommonDto> result;
        switch (type) {
            case 1:
                result = itemLargeScreenMapper.rankByDepartment(dto);
                break;
            case 2:
                result = itemLargeScreenMapper.rankByTeam(dto);
                break;
            case 3:
                result = itemLargeScreenMapper.rankByIndividual(dto);
                for (ItemLargeScreenCommonDto itemLargeScreenCommonDto : result) {
                    if (Objects.nonNull(itemLargeScreenCommonDto)) {
                        SysUser sysUser = sysUserService.selectUserById(itemLargeScreenCommonDto.getId());
                        if (Objects.nonNull(sysUser)) {
                            itemLargeScreenCommonDto.setName(sysUser.getNickName());
                        }
                    }
                }
                break;
            case 4:
                result = itemLargeScreenMapper.rankByBrigade(dto);
                break;
            default:
                return Collections.emptyList();
        }
        result.forEach(item -> item.setScale(item.getTotal().multiply(new BigDecimal("100")).divide(totalSum, 2, BigDecimal.ROUND_HALF_UP)));
        return result;
    }

    /**
     * 查获时段分布
     *
     * @param dto 大屏查询参数
     * @return 查获时段分布
     */
    @Override
    public List<ItemLargeScreenTimeSpanDto> timeSpan(BaseLargeScreenQueryParamDto dto) {
        if (dto.getSpecifiedDate() == null) {
            dto.setSpecifiedDate(Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant()));
        }
        return itemLargeScreenMapper.timeSpan(dto);
    }

    /**
     * app端 查获时段分布
     *
     * @param dto 大屏查询参数
     * @return 查获时段分布
     */
    @Override
    public List<ItemLargeScreenTimeSpanDto> appTimeSpan(BaseLargeScreenQueryParamDto dto) {
        return itemLargeScreenMapper.timeSpan(dto);
    }


    /**
     * 查获位置分布
     *
     * @param dto 大屏查询参数
     * @return 查获位置分布
     */
    @Override
    public List<ItemLargeScreenPositionDto> position(BaseLargeScreenQueryParamDto dto) {
        List<ItemLargeScreenPositionDto> positions = itemLargeScreenMapper.position(dto);
        if (!positions.isEmpty()) {
            positions.forEach(p -> {
                if (p.getCheckPositionNameOne() != null && p.getCheckPositionNameOne().contains("/")) {
                    String[] arr = p.getCheckPositionNameOne().split("/", 2);
                    p.setCheckPositionNameOne(arr[0]);
                    p.setCheckPositionNameTwo(arr[1]);
                }
            });


            // 3. 分组并追加汇总
            List<ItemLargeScreenPositionDto> result = new ArrayList<>();
            Map<String, List<ItemLargeScreenPositionDto>> grouped =
                    positions.stream().collect(Collectors.groupingBy(ItemLargeScreenPositionDto::getCheckPositionNameOne));

            grouped.forEach((groupName, groupList) -> {
                // 3.1 先加入组内原始数据
                result.addAll(groupList);

                // 3.2 计算组内 BigDecimal 总和
                BigDecimal sum = groupList.stream()
                        .map(ItemLargeScreenPositionDto::getTotal)
                        .filter(Objects::nonNull)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);

                // 3.3 构造汇总记录
                ItemLargeScreenPositionDto summary = new ItemLargeScreenPositionDto();
                summary.setCheckPositionCodeOne("TOTAL"); // 可自定义
                summary.setCheckPositionNameOne(groupName);
                summary.setCheckPositionCodeTwo("无");
                summary.setCheckPositionNameTwo("无");
                summary.setTotal(sum);

                result.add(summary);
            });
            // 按拆分后的 checkPositionNameOne 升序
            result.sort(
                    Comparator.comparing(ItemLargeScreenPositionDto::getCheckPositionNameOne,
                            Comparator.nullsFirst(String::compareTo))
            );

            return result;
        }
        return positions;
    }

    /**
     * app端 查获位置分布
     *
     * @param dto
     * @return
     */
    @Override
    public List<ItemLargeScreenPositionAppDto> appPosition(BaseLargeScreenQueryParamDto dto) {
        return itemLargeScreenMapper.appPosition(dto);
    }

    /**
     * 查获通道分布
     *
     * @param dto 大屏查询参数
     * @return 查获通道分布
     */
    @Override
    public List<ItemLargeScreenChannelDto> channel(BaseLargeScreenQueryParamDto dto) {
        return itemLargeScreenMapper.channel(dto);
    }

    /**
     * 使用报表-运行情况-查获模块
     *
     * @param dto 大屏查询参数
     * @return 使用报表-运行情况-查获模块
     */
    @Override
    public SysUsageReportDto.SeizureModule getSeizureModule(BaseLargeScreenQueryParamDto dto) {
        SysUsageReportDto.SeizureModule seizureModule = new SysUsageReportDto.SeizureModule();
        List<SysUsageReportSeizureDto> dataList = itemLargeScreenMapper.getSeizureModule(dto);
        if (CollUtil.isEmpty(dataList)) {
            return null;
        }
        seizureModule.setTotalForm((int) dataList.stream().map(SysUsageReportSeizureDto::getId).distinct().count());
        dataList = dataList.stream().filter(d -> StrUtil.equals("3", d.getProcessStatus())).collect(Collectors.toList());
        seizureModule.setTotalFormArchived((int) dataList.stream().map(SysUsageReportSeizureDto::getId).distinct().count());
        seizureModule.setTotalSeizure(dataList.stream().map(SysUsageReportSeizureDto::getTotal).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add));
        seizureModule.setSeizureTypeList(convertAndGroupByField(dataList, d -> d.getCategoryCode() + "###" + d.getCategoryName()));
        seizureModule.setSeizurePositionList(convertAndGroupByField(dataList, d -> d.getPositionCode() + "###" + d.getPositionName()));
        List<BaseCommonDto> allParts = convertAndGroupByField(dataList, d -> d.getPartCode() + "###" + d.getPartName());
        allParts.forEach(item -> {
            item.setScale(seizureModule.getTotalSeizure().compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : item.getTotal().divide(seizureModule.getTotalSeizure(), 4, RoundingMode.HALF_UP));
            item.setScaleDesc(item.getScale().multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP) + "%");
        });
        seizureModule.setSeizurePartList(allParts);
        List<BaseCommonDto> hiddenParts = convertAndGroupByField(dataList.stream().filter(item -> item.getHidden() != null && item.getHidden() == 1).collect(Collectors.toList()), d -> d.getPartCode() + "###" + d.getPartName());
        seizureModule.setSeizurePartHiddenList(hiddenParts);
        return seizureModule;
    }

    /**
     * 按指定字段分组汇总数量（通用方法）
     *
     * @param sourceList   原始数据列表
     * @param keyExtractor 分组键提取函数
     * @return 转换后数据列表
     */
    private List<BaseCommonDto> convertAndGroupByField(List<SysUsageReportSeizureDto> sourceList, Function<SysUsageReportSeizureDto, String> keyExtractor) {
        if (CollUtil.isEmpty(sourceList)) {
            return Collections.emptyList();
        }
        Map<String, BigDecimal> groupedTotals = sourceList.stream()
                .filter(dto -> dto.getTotal() != null)
                .filter(dto -> {
                    String key = keyExtractor.apply(dto);
                    return key != null && !key.contains("null");
                })
                .collect(Collectors.groupingBy(
                        keyExtractor,
                        Collectors.reducing(BigDecimal.ZERO,
                                SysUsageReportSeizureDto::getTotal,
                                BigDecimal::add)
                ));
        return groupedTotals.entrySet().stream()
                .map(entry -> {
                    String[] parts = entry.getKey().split("###", 2);
                    BaseCommonDto dto = new BaseCommonDto();
                    dto.setCode(parts.length > 0 ? parts[0] : "");
                    dto.setName(parts.length > 1 ? parts[1] : "");
                    dto.setTotal(entry.getValue());
                    return dto;
                })
                .sorted(Comparator.comparing(BaseCommonDto::getTotal).reversed())
                .collect(Collectors.toList());
    }

    /**
     * 移交公安数据统计（查获总数 + 大队排名）
     *
     * @param dto 大屏查询参数
     * @return 移交公安数据统计
     */
    @Override
    public ItemLargeScreenPoliceStatsDto getPoliceStats(BaseLargeScreenQueryParamDto dto) {
        // 1. 查询移交公安的明细数据
        List<ItemLargeScreenInfoDto> policeList = itemLargeScreenMapper.police(dto);

        // 2. 计算查获总数量
        BigDecimal totalQuantity = policeList.stream()
                .map(ItemLargeScreenInfoDto::getQuantity)
                .filter(java.util.Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // 3. 根据参数判断分组和排序维度
        List<ItemLargeScreenBrigadeRankDto> brigadeRankList;

        if (dto.getUserId() != null) {
            brigadeRankList = new ArrayList<>();
        } else if (dto.getInspectTeamId() != null) {
            // 传入了班 ID，按个人分组统计
            brigadeRankList = groupAndRankByUser(policeList, totalQuantity);
        } else if (dto.getInspectDepartmentId() != null) {
            // 传入了科室 ID，按班组分组统计
            brigadeRankList = groupAndRankByTeam(policeList, totalQuantity);
        } else if (dto.getInspectBrigadeId() != null) {
            // 默认（站级别），按科室分组统计
            brigadeRankList = groupAndRankByDepartment(policeList, totalQuantity);
        } else {
            brigadeRankList = groupAndRankByBrigade(policeList, totalQuantity);
        }

        // 4. 构造返回结果
        ItemLargeScreenPoliceStatsDto result = new ItemLargeScreenPoliceStatsDto();
        result.setTotalQuantity(totalQuantity);
        result.setBrigadeRankList(brigadeRankList);

        return result;
    }

    /**
     * 按大队分组统计并排序（站级别使用）
     */
    private List<ItemLargeScreenBrigadeRankDto> groupAndRankByBrigade(List<ItemLargeScreenInfoDto> dataList, BigDecimal totalQuantity) {
        // 按科室分组
        Map<String, List<ItemLargeScreenInfoDto>> groupedByBrigade = dataList.stream()
                .collect(Collectors.groupingBy(item ->
                        item.getInspectBrigadeId() + "###" + item.getInspectBrigadeName()));

        // 转换为科室排名列表
        List<ItemLargeScreenBrigadeRankDto> rankList = groupedByBrigade.entrySet().stream()
                .map(entry -> {
                    ItemLargeScreenBrigadeRankDto rankDto = new ItemLargeScreenBrigadeRankDto();
                    List<ItemLargeScreenInfoDto> items = entry.getValue();

                    if (!items.isEmpty()) {
                        ItemLargeScreenInfoDto firstItem = items.get(0);
                        rankDto.setBrigadeId(firstItem.getInspectDepartmentId());
                        rankDto.setBrigadeName(firstItem.getInspectDepartmentName());

                        // 计算该科室的查获总数量
                        BigDecimal deptQuantity = items.stream()
                                .map(ItemLargeScreenInfoDto::getQuantity)
                                .filter(java.util.Objects::nonNull)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                        rankDto.setQuantity(deptQuantity);

                        // 计算占比
                        if (totalQuantity.compareTo(BigDecimal.ZERO) > 0) {
                            rankDto.setScale(deptQuantity.multiply(new BigDecimal("100"))
                                    .divide(totalQuantity, 2, BigDecimal.ROUND_HALF_UP));
                        } else {
                            rankDto.setScale(BigDecimal.ZERO);
                        }
                    }

                    return rankDto;
                })
                .sorted(Comparator.comparing(ItemLargeScreenBrigadeRankDto::getQuantity).reversed())
                .collect(Collectors.toList());

        // 设置排名
        for (int i = 0; i < rankList.size(); i++) {
            rankList.get(i).setRank(i + 1);
        }

        return rankList;
    }

    /**
     * 按科室分组统计并排序（大队级别使用）
     */
    private List<ItemLargeScreenBrigadeRankDto> groupAndRankByDepartment(List<ItemLargeScreenInfoDto> dataList, BigDecimal totalQuantity) {
        // 按科室分组
        Map<String, List<ItemLargeScreenInfoDto>> groupedByDepartment = dataList.stream()
                .collect(Collectors.groupingBy(item ->
                        item.getInspectDepartmentId() + "###" + item.getInspectDepartmentName()));

        // 转换为科室排名列表
        List<ItemLargeScreenBrigadeRankDto> rankList = groupedByDepartment.entrySet().stream()
                .map(entry -> {
                    ItemLargeScreenBrigadeRankDto rankDto = new ItemLargeScreenBrigadeRankDto();
                    List<ItemLargeScreenInfoDto> items = entry.getValue();

                    if (!items.isEmpty()) {
                        ItemLargeScreenInfoDto firstItem = items.get(0);
                        rankDto.setBrigadeId(firstItem.getInspectDepartmentId());
                        rankDto.setBrigadeName(firstItem.getInspectDepartmentName());

                        // 计算该科室的查获总数量
                        BigDecimal deptQuantity = items.stream()
                                .map(ItemLargeScreenInfoDto::getQuantity)
                                .filter(java.util.Objects::nonNull)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                        rankDto.setQuantity(deptQuantity);

                        // 计算占比
                        if (totalQuantity.compareTo(BigDecimal.ZERO) > 0) {
                            rankDto.setScale(deptQuantity.multiply(new BigDecimal("100"))
                                    .divide(totalQuantity, 2, BigDecimal.ROUND_HALF_UP));
                        } else {
                            rankDto.setScale(BigDecimal.ZERO);
                        }
                    }

                    return rankDto;
                })
                .sorted(Comparator.comparing(ItemLargeScreenBrigadeRankDto::getQuantity).reversed())
                .collect(Collectors.toList());

        // 设置排名
        for (int i = 0; i < rankList.size(); i++) {
            rankList.get(i).setRank(i + 1);
        }

        return rankList;
    }

    /**
     * 按班组分组统计并排序
     */
    private List<ItemLargeScreenBrigadeRankDto> groupAndRankByTeam(List<ItemLargeScreenInfoDto> dataList, BigDecimal totalQuantity) {
        // 按班组分组
        Map<String, List<ItemLargeScreenInfoDto>> groupedByTeam = dataList.stream()
                .collect(Collectors.groupingBy(item ->
                        item.getInspectTeamId() + "###" + item.getInspectTeamName()));

        // 转换为班组排名列表
        List<ItemLargeScreenBrigadeRankDto> rankList = groupedByTeam.entrySet().stream()
                .map(entry -> {
                    ItemLargeScreenBrigadeRankDto rankDto = new ItemLargeScreenBrigadeRankDto();
                    List<ItemLargeScreenInfoDto> items = entry.getValue();

                    if (!items.isEmpty()) {
                        ItemLargeScreenInfoDto firstItem = items.get(0);
                        rankDto.setBrigadeId(firstItem.getInspectTeamId());
                        rankDto.setBrigadeName(firstItem.getInspectTeamName());

                        // 计算该班组的查获总数量
                        BigDecimal teamQuantity = items.stream()
                                .map(ItemLargeScreenInfoDto::getQuantity)
                                .filter(java.util.Objects::nonNull)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                        rankDto.setQuantity(teamQuantity);

                        // 计算占比
                        if (totalQuantity.compareTo(BigDecimal.ZERO) > 0) {
                            rankDto.setScale(teamQuantity.multiply(new BigDecimal("100"))
                                    .divide(totalQuantity, 2, BigDecimal.ROUND_HALF_UP));
                        } else {
                            rankDto.setScale(BigDecimal.ZERO);
                        }
                    }

                    return rankDto;
                })
                .sorted(Comparator.comparing(ItemLargeScreenBrigadeRankDto::getQuantity).reversed())
                .collect(Collectors.toList());

        // 设置排名
        for (int i = 0; i < rankList.size(); i++) {
            rankList.get(i).setRank(i + 1);
        }

        return rankList;
    }

    /**
     * 按个人分组统计并排序
     */
    private List<ItemLargeScreenBrigadeRankDto> groupAndRankByUser(List<ItemLargeScreenInfoDto> dataList, BigDecimal totalQuantity) {
        // 按个人分组
        Map<String, List<ItemLargeScreenInfoDto>> groupedByUser = dataList.stream()
                .collect(Collectors.groupingBy(item ->
                        item.getInspectUserId() + "###" + item.getInspectUserName()));

        // 转换为个人排名列表
        List<ItemLargeScreenBrigadeRankDto> rankList = groupedByUser.entrySet().stream()
                .map(entry -> {
                    ItemLargeScreenBrigadeRankDto rankDto = new ItemLargeScreenBrigadeRankDto();
                    List<ItemLargeScreenInfoDto> items = entry.getValue();

                    if (!items.isEmpty()) {
                        ItemLargeScreenInfoDto firstItem = items.get(0);
                        rankDto.setBrigadeId(firstItem.getInspectUserId());
                        rankDto.setBrigadeName(firstItem.getInspectUserName());

                        // 计算个人的查获总数量
                        BigDecimal userQuantity = items.stream()
                                .map(ItemLargeScreenInfoDto::getQuantity)
                                .filter(java.util.Objects::nonNull)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                        rankDto.setQuantity(userQuantity);

                        // 计算占比
                        if (totalQuantity.compareTo(BigDecimal.ZERO) > 0) {
                            rankDto.setScale(userQuantity.multiply(new BigDecimal("100"))
                                    .divide(totalQuantity, 2, BigDecimal.ROUND_HALF_UP));
                        } else {
                            rankDto.setScale(BigDecimal.ZERO);
                        }
                    }

                    return rankDto;
                })
                .sorted(Comparator.comparing(ItemLargeScreenBrigadeRankDto::getQuantity).reversed())
                .collect(Collectors.toList());

        // 设置排名
        for (int i = 0; i < rankList.size(); i++) {
            rankList.get(i).setRank(i + 1);
        }

        return rankList;
    }

    /**
     * X 光机漏检数据
     *
     * @param dto 大屏查询参数
     * @return X 光机漏检数据
     */
    @Override
    public List<ItemXRayMissCheckDto> xRayMissCheck(BaseLargeScreenQueryParamDto dto) {
        return itemLargeScreenMapper.xRayMissCheck(dto);
    }

    /**
     * X 光机漏检人员统计 TOP3
     *
     * @param dto 大屏查询参数
     * @return X 光机漏检人员统计 TOP3
     */
    @Override
    public List<ItemXRayMissCheckUserStatsDto> xRayMissCheckUserStatsTop3(BaseLargeScreenQueryParamDto dto) {
        // 直接查询并返回前 3 名
        return itemLargeScreenMapper.xRayMissCheckUserStatsTop3(dto);
    }

    /**
     * 异常查获数据
     *
     * @param dto 大屏查询参数
     * @return 异常查获数据
     */
    @Override
    public List<ItemAbnormalSeizureDto> getAbnormalSeizureData(BaseLargeScreenQueryParamDto dto) {
        // 1. 获取箱线图数据（用于获取上下限）
        List<GroupedBoxPlotDataDto> boxPlotDataList = seizureDistributionService.calculateBoxPlotData(dto);

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

        // 2. 获取站级数据（第一个分组）的上下限
        BigDecimal lowerBound = BigDecimal.ZERO;
        BigDecimal upperBound = BigDecimal.ZERO;

        if (dto.getInspectBrigadeId() != null) {
            // 根据 id 获取部门信息
            SysDept dept = sysDeptService.selectDeptById(dto.getInspectBrigadeId());
            if (Objects.isNull(dept)) {
                return Collections.emptyList();
            }

            // 查找匹配的分组数据
            Optional<GroupedBoxPlotDataDto> matchedGroup = boxPlotDataList.stream()
                    .filter(grouped -> Objects.equals(grouped.getGroupName(), dept.getDeptName()))
                    .findFirst();

            if (matchedGroup.isPresent()) {
                BoxPlotDataDto boxPlotData = matchedGroup.get().getBoxPlotData();
                if (Objects.nonNull(boxPlotData)) {
                    lowerBound = boxPlotData.getLowerBound();
                    upperBound = boxPlotData.getUpperBound();
                }
            }
        } else if (dto.getInspectDepartmentId() != null) {
            // 根据 id 获取部门信息
            SysDept dept = sysDeptService.selectDeptById(dto.getInspectDepartmentId());
            if (Objects.isNull(dept)) {
                return Collections.emptyList();
            }

            // 查找匹配的分组数据
            Optional<GroupedBoxPlotDataDto> matchedGroup = boxPlotDataList.stream()
                    .filter(grouped -> Objects.equals(grouped.getGroupName(), dept.getDeptName()))
                    .findFirst();

            if (matchedGroup.isPresent()) {
                BoxPlotDataDto boxPlotData = matchedGroup.get().getBoxPlotData();
                if (Objects.nonNull(boxPlotData)) {
                    lowerBound = boxPlotData.getLowerBound();
                    upperBound = boxPlotData.getUpperBound();
                }
            }
        } else {
            GroupedBoxPlotDataDto firstGroup = boxPlotDataList.get(0);
            if (Objects.nonNull(firstGroup) && Objects.nonNull(firstGroup.getBoxPlotData())) {
                BoxPlotDataDto boxPlotData = firstGroup.getBoxPlotData();
                lowerBound = boxPlotData.getLowerBound();
                upperBound = boxPlotData.getUpperBound();
            }
        }


        // 3. 查询用户信息和查获数量
        List<ItemLargeScreenHomePageSeizureReportSqlDto> seizureReportList;
        List<LargeScreenHomePageUserInfoSqlDto> userInfoList;

        if (dto.getInspectBrigadeId() != null) {
            // 有大队 ID，查询大队数据
            seizureReportList = seizureReportMapper.homePageSeizureReportBrigadeId(dto);
            userInfoList = sysUserService.homePageUserInfoByBrigadeId(dto.getInspectBrigadeId());
        } else if (dto.getInspectDepartmentId() != null) {
            // 有科室 ID，查询科室数据
            seizureReportList = seizureReportMapper.homePageSeizureReportDepartmentId(dto);
            userInfoList = sysUserService.homePageUserInfoByDepartmentId(dto.getInspectDepartmentId());
        } else {
            // 无大队 ID，查询全站数据
            seizureReportList = seizureReportMapper.homePageSeizureReport(dto);
            userInfoList = sysUserService.homePageUserInfo();
        }

        if (CollUtil.isEmpty(seizureReportList) || CollUtil.isEmpty(userInfoList)) {
            return Collections.emptyList();
        }

        // 4. 按用户分组统计查获总数
        Map<Long, BigDecimal> userSeizureMap = seizureReportList.stream()
                .collect(Collectors.groupingBy(
                        ItemLargeScreenHomePageSeizureReportSqlDto::getUserId,
                        Collectors.reducing(BigDecimal.ZERO, ItemLargeScreenHomePageSeizureReportSqlDto::getQuantity, BigDecimal::add)
                ));

        // 5. 筛选出异常值
        List<ItemAbnormalSeizureDto> abnormalList = new ArrayList<>();

        for (LargeScreenHomePageUserInfoSqlDto userInfo : userInfoList) {
            BigDecimal totalQuantity = userSeizureMap.getOrDefault(userInfo.getUserId(), BigDecimal.ZERO);

            if (lowerBound == null || upperBound == null) {
                continue;
            }

            // 判断是否为异常值
            if (totalQuantity.compareTo(lowerBound) < 0 || totalQuantity.compareTo(upperBound) > 0) {
                ItemAbnormalSeizureDto abnormalDto = new ItemAbnormalSeizureDto();
                abnormalDto.setBrigadeName(userInfo.getBrigadeName());
                abnormalDto.setDepartmentName(userInfo.getDepartmentName());
                abnormalDto.setTeamName(userInfo.getTeamName());
                abnormalDto.setUserName(userInfo.getNickName());
                abnormalDto.setSeizureQuantity(totalQuantity);
                abnormalList.add(abnormalDto);
            }
        }

        return abnormalList;
    }

    /**
     * 异常查获数据 TOP3（3 个高于 +3 个低于）
     *
     * @param dto 大屏查询参数
     * @return 异常查获数据 TOP3
     */
    @Override
    public ItemAbnormalSeizureRankDto getAbnormalSeizureDataTop3(BaseLargeScreenQueryParamDto dto) {
        ItemAbnormalSeizureRankDto result = new ItemAbnormalSeizureRankDto();
        // 1. 获取箱线图数据（用于获取上下限）
        List<GroupedBoxPlotDataDto> boxPlotDataList = seizureDistributionService.calculateBoxPlotData(dto);

        if (boxPlotDataList == null || boxPlotDataList.isEmpty()) {
            return result;
        }

        // 2. 获取站级数据（第一个分组）的上下限
        BigDecimal lowerBound = BigDecimal.ZERO;
        BigDecimal upperBound = BigDecimal.ZERO;


        if (dto.getInspectBrigadeId() != null) {
            // 根据 id 获取部门信息
            SysDept dept = sysDeptService.selectDeptById(dto.getInspectBrigadeId());
            if (Objects.isNull(dept)) {
                return result;
            }

            // 查找匹配的分组数据
            Optional<GroupedBoxPlotDataDto> matchedGroup = boxPlotDataList.stream()
                    .filter(grouped -> Objects.equals(grouped.getGroupName(), dept.getDeptName()))
                    .findFirst();

            if (matchedGroup.isPresent()) {
                BoxPlotDataDto boxPlotData = matchedGroup.get().getBoxPlotData();
                if (Objects.nonNull(boxPlotData)) {
                    lowerBound = boxPlotData.getLowerBound();
                    upperBound = boxPlotData.getUpperBound();
                }
            }
        } else if (dto.getInspectDepartmentId() != null) {
            // 根据 id 获取部门信息
            SysDept dept = sysDeptService.selectDeptById(dto.getInspectDepartmentId());
            if (Objects.isNull(dept)) {
                return result;
            }

            // 查找匹配的分组数据
            Optional<GroupedBoxPlotDataDto> matchedGroup = boxPlotDataList.stream()
                    .filter(grouped -> Objects.equals(grouped.getGroupName(), dept.getDeptName()))
                    .findFirst();

            if (matchedGroup.isPresent()) {
                BoxPlotDataDto boxPlotData = matchedGroup.get().getBoxPlotData();
                if (Objects.nonNull(boxPlotData)) {
                    lowerBound = boxPlotData.getLowerBound();
                    upperBound = boxPlotData.getUpperBound();
                }
            }
        } else {
            GroupedBoxPlotDataDto firstGroup = boxPlotDataList.get(0);
            if (Objects.nonNull(firstGroup) && Objects.nonNull(firstGroup.getBoxPlotData())) {
                BoxPlotDataDto boxPlotData = firstGroup.getBoxPlotData();
                lowerBound = boxPlotData.getLowerBound();
                upperBound = boxPlotData.getUpperBound();
            }
        }

        // 3. 查询用户信息和查获数量
        List<ItemLargeScreenHomePageSeizureReportSqlDto> seizureReportList;
        List<LargeScreenHomePageUserInfoSqlDto> userInfoList;

        if (dto.getInspectBrigadeId() != null) {
            // 有大队 ID，查询大队数据
            seizureReportList = seizureReportMapper.homePageSeizureReportBrigadeId(dto);
            userInfoList = sysUserService.homePageUserInfoByBrigadeId(dto.getInspectBrigadeId());
        } else if (dto.getInspectDepartmentId() != null) {
            // 有科室 ID，查询科室数据
            seizureReportList = seizureReportMapper.homePageSeizureReportDepartmentId(dto);
            userInfoList = sysUserService.homePageUserInfoByDepartmentId(dto.getInspectDepartmentId());
        } else {
            // 无大队 ID，查询全站数据
            seizureReportList = seizureReportMapper.homePageSeizureReport(dto);
            userInfoList = sysUserService.homePageUserInfo();
        }

        if (CollUtil.isEmpty(seizureReportList) || CollUtil.isEmpty(userInfoList)) {
            return result;
        }

        // 4. 按用户分组统计查获总数
        Map<Long, BigDecimal> userSeizureMap = seizureReportList.stream()
                .collect(Collectors.groupingBy(
                        ItemLargeScreenHomePageSeizureReportSqlDto::getUserId,
                        Collectors.reducing(BigDecimal.ZERO, ItemLargeScreenHomePageSeizureReportSqlDto::getQuantity, BigDecimal::add)
                ));

        // 5. 筛选出异常值并分类
        List<ItemAbnormalSeizureDto> higherList = new ArrayList<>();
        List<ItemAbnormalSeizureDto> lowerList = new ArrayList<>();

        for (LargeScreenHomePageUserInfoSqlDto userInfo : userInfoList) {
            BigDecimal totalQuantity = userSeizureMap.getOrDefault(userInfo.getUserId(), BigDecimal.ZERO);

            if (lowerBound == null || upperBound == null) {
                continue;
            }

            // 判断是否为异常值
            if (totalQuantity.compareTo(upperBound) > 0) {
                // 显著高于
                ItemAbnormalSeizureDto abnormalDto = new ItemAbnormalSeizureDto();
                abnormalDto.setBrigadeName(userInfo.getBrigadeName());
                abnormalDto.setDepartmentName(userInfo.getDepartmentName());
                abnormalDto.setTeamName(userInfo.getTeamName());
                abnormalDto.setUserName(userInfo.getNickName());
                abnormalDto.setSeizureQuantity(totalQuantity);
                higherList.add(abnormalDto);
            } else if (totalQuantity.compareTo(lowerBound) < 0) {
                // 显著低于
                ItemAbnormalSeizureDto abnormalDto = new ItemAbnormalSeizureDto();
                abnormalDto.setBrigadeName(userInfo.getBrigadeName());
                abnormalDto.setDepartmentName(userInfo.getDepartmentName());
                abnormalDto.setTeamName(userInfo.getTeamName());
                abnormalDto.setUserName(userInfo.getNickName());
                abnormalDto.setSeizureQuantity(totalQuantity);
                lowerList.add(abnormalDto);
            }
        }

        // 6. 排序并设置排名
        higherList.sort(Comparator.comparing(ItemAbnormalSeizureDto::getSeizureQuantity).reversed());
        lowerList.sort(Comparator.comparing(ItemAbnormalSeizureDto::getSeizureQuantity));

        for (int i = 0; i < higherList.size(); i++) {
            higherList.get(i).setRank(i + 1);
        }

        for (int i = 0; i < lowerList.size(); i++) {
            lowerList.get(i).setRank(i + 1);
        }

        // 7. 取前 3 个
        int higherCount = Math.min(3, higherList.size());
        int lowerCount = Math.min(3, lowerList.size());
        List<ItemAbnormalSeizureDto> lowList = new ArrayList<>();
        List<ItemAbnormalSeizureDto> higList = new ArrayList<>();

        // 添加高于的 3 个
        for (int i = 0; i < higherCount; i++) {
            higList.add(higherList.get(i));
        }
        result.setHigList(higList);

        // 添加低于的 3 个
        for (int i = 0; i < lowerCount; i++) {
            lowList.add(lowerList.get(i));
        }
        result.setLowList(lowList);
        return result;
    }

}
