package com.sundot.airport.item.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.sundot.airport.common.core.domain.BaseLargeScreenQueryParamDto;
import com.sundot.airport.common.core.domain.DataPermissionResult;
import com.sundot.airport.common.core.domain.LargeScreenHomePageUserInfoSqlDto;
import com.sundot.airport.common.core.domain.SeizureLargeScreenHomePageItemDto;
import com.sundot.airport.common.core.domain.SysHomeReportDetailDto;
import com.sundot.airport.common.core.domain.entity.SysDept;
import com.sundot.airport.common.core.domain.entity.SysRole;
import com.sundot.airport.common.core.domain.entity.SysUser;
import com.sundot.airport.common.core.domain.model.LoginUser;
import com.sundot.airport.common.enums.DataPermissionType;
import com.sundot.airport.common.enums.DeptType;
import com.sundot.airport.common.enums.HomePageQueryEnum;
import com.sundot.airport.common.enums.RoleTypeEnum;
import com.sundot.airport.common.enums.SourceTypeEnum;
import com.sundot.airport.common.exception.ServiceException;
import com.sundot.airport.common.utils.DateUtils;
import com.sundot.airport.common.utils.LargeScreenDateUtils;
import com.sundot.airport.common.utils.SecurityUtils;
import com.sundot.airport.item.domain.FailedMatchItem;
import com.sundot.airport.item.domain.ItemLargeScreenHomePageSeizureReportSqlDto;
import com.sundot.airport.item.domain.home.*;
import com.sundot.airport.system.service.ISysDeptService;
import com.sundot.airport.item.mapper.SeizureReportMapper;
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.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.sundot.airport.common.utils.SecurityUtils.getLoginUser;

/**
 * 查获上报 Service层
 */
@Service
public class SeizureReportService {

    @Autowired
    private SeizureReportMapper seizureReportMapper;

    @Autowired
    private ISysDeptService sysDeptService;

    @Autowired
    private IFailedMatchItemService failedMatchItemService;

    @Autowired
    private ISysUserService sysUserService;

    /**
     * 获取按角色分类的查获上报数据
     */
    public RoleBasedSeizureReportDTO getRoleBasedSeizureReportData(Long userId, Long deptId, java.util.Date startDate, java.util.Date endDate, String timeRange, String dataSource, String source) {
        // 1. 计算时间范围
        if (startDate == null || endDate == null) {
            java.util.Date[] timeRangeDates = calculateTimeRange(timeRange);
            startDate = timeRangeDates[0];
            endDate = timeRangeDates[1];
        }
        if (endDate != null) {
            endDate = DateUtils.addSeconds(DateUtils.truncate(endDate, Calendar.DAY_OF_MONTH), 86399);
        }

        // 2. 获取数据权限
        DataPermissionResult permissionResult = getDataPermission(userId, deptId);

        // 3. 创建返回对象
        RoleBasedSeizureReportDTO roleBasedDto = new RoleBasedSeizureReportDTO();
        // 4. 根据权限类型设置查询条件
        if (StrUtil.equals(SourceTypeEnum.mobile.getCode(), source)) {
            if (permissionResult.getPermissionType() == DataPermissionType.SELF || (permissionResult.getPermissionType() == DataPermissionType.TEAM && "individual".equalsIgnoreCase(dataSource))) {
                // 安检员数据 - 个人数据
                SecurityCheckerSeizureReportDTO securityCheckerData = new SecurityCheckerSeizureReportDTO();
                handleSecurityCheckRoleForSpecificDTO(userId, deptId, startDate, endDate, securityCheckerData);
                roleBasedDto.setSecurityCheckerData(securityCheckerData);
            } else if (permissionResult.getPermissionType() == DataPermissionType.TEAM && "team".equalsIgnoreCase(dataSource)) {
                // 班组长数据 - 班组数据
                TeamLeaderSeizureReportDTO teamLeaderData = new TeamLeaderSeizureReportDTO();
                handleTeamLeaderRoleForSpecificDTO(userId, deptId, startDate, endDate, teamLeaderData);
                roleBasedDto.setTeamLeaderData(teamLeaderData);
            } else if (permissionResult.getPermissionType() == DataPermissionType.DEPARTMENT) {
                // 科长数据 - 科室数据
                SectionMasterSeizureReportDTO sectionMasterData = new SectionMasterSeizureReportDTO();
                handleSectionLeaderRoleForSpecificDTO(userId, deptId, startDate, endDate, sectionMasterData);
                roleBasedDto.setSectionMasterData(sectionMasterData);
            } else if (permissionResult.getPermissionType() == DataPermissionType.BRIGADE) {
                // 经理和大队行政数据 - 大队数据
                BrigadeLeaderSeizureReportDTO brigadeLeaderData = new BrigadeLeaderSeizureReportDTO();
                handleBrigadeLeaderRoleForSpecificDTO(userId, deptId, startDate, endDate, brigadeLeaderData);
                roleBasedDto.setBrigadeMasterData(brigadeLeaderData);
            } else if (permissionResult.getPermissionType() == DataPermissionType.STATION || permissionResult.getPermissionType() == DataPermissionType.ALL) {
                // 站长数据 - 全站数据
                StationLeaderSeizureReportDTO stationMasterData = new StationLeaderSeizureReportDTO();
                handleStationLeaderRoleForSpecificDTO(userId, deptId, startDate, endDate, stationMasterData);
                roleBasedDto.setStationMasterData(stationMasterData);
            }
        } else {
            List<SysDept> sysDeptList = sysDeptService.selectAllDept(SecurityUtils.getLoginUser().getDeptId());
            Collections.reverse(sysDeptList);
            SysDept stationDept = sysDeptList.stream().filter(x -> StrUtil.equals(DeptType.STATION.getCode(), x.getDeptType())).findFirst().orElse(null);
            if (ObjectUtil.isNull(stationDept)) {
                throw new ServiceException("未查询到站级部门信息");
            }
            // 站长数据 - 全站数据
            StationLeaderSeizureReportDTO stationMasterData = new StationLeaderSeizureReportDTO();
            handleStationLeaderRoleForSpecificDTO(userId, deptId, startDate, endDate, stationMasterData);
            roleBasedDto.setStationMasterData(stationMasterData);
        }

        return roleBasedDto;
    }

    /**
     * 计算时间范围
     *
     * @param timeRange 时间范围类型
     * @return [开始日期, 结束日期]
     */
    private java.util.Date[] calculateTimeRange(String timeRange) {
        java.util.Date endDate = DateUtils.addDays(new java.util.Date(), -1); // 不包括今天
        java.util.Date startDate;

        if ("week".equals(timeRange)) {
            startDate = DateUtils.addDays(endDate, -7); // 近一周
        } else if ("month".equals(timeRange)) {
            startDate = DateUtils.addDays(endDate, -30); // 近一月
        } else if ("quarter".equals(timeRange)) {
            startDate = DateUtils.addDays(endDate, -90); // 近三月
        } else if ("half_year".equals(timeRange)) {
            startDate = DateUtils.addDays(endDate, -180); // 近半年
        } else if ("year".equals(timeRange) || timeRange == null) {
            startDate = DateUtils.addDays(endDate, -365); // 近一年，默认选择
        } else {
            // 如果是自定义时间，startDate和endDate应直接传入
            startDate = DateUtils.addDays(endDate, -365); // 默认近一年
        }

        return new java.util.Date[]{startDate, endDate};
    }


    /**
     * 处理安检员角色
     */
    private void handleSecurityCheckRoleForSpecificDTO(Long userId, Long deptId, java.util.Date startDate, java.util.Date endDate, SecurityCheckerSeizureReportDTO dto) {
        // 本人查获数量
        BigDecimal selfSeizureCount = seizureReportMapper.selectSelfSeizureCount(userId, startDate, endDate);
        dto.setSelfSeizureCount(selfSeizureCount);

        // 班组平均数 - 现在先获取总查获数，再除以人数
        BigDecimal totalTeamSeizure = seizureReportMapper.selectTeamAverage(deptId, startDate, endDate); // 这个方法现在返回总查获数
        Integer teamUserCount = seizureReportMapper.selectUserCountByTeamId(deptId); // 获取班组人数
        BigDecimal teamAverage = (teamUserCount != null && teamUserCount > 0) ?
                totalTeamSeizure.divide(new BigDecimal(teamUserCount), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO;
        dto.setTeamAverage(teamAverage);

        // 科室平均数 = 科室查获总数 / 科室下所有班组长和安检员数量
        Long sectionDeptId = getSectionDeptId(deptId);
        BigDecimal totalDepartmentSeizure = seizureReportMapper.selectDepartmentAverage(sectionDeptId, startDate, endDate);
        Integer deptUserCount = seizureReportMapper.selectUserCountByDepartmentId(sectionDeptId);
        BigDecimal sectionAverage = (deptUserCount != null && deptUserCount > 0) ?
                totalDepartmentSeizure.divide(new BigDecimal(deptUserCount), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO;
        dto.setDepartmentAverage(sectionAverage);

        // 大队平均数 = 大队查获总数 / 大队下所有班组长和安检员数量
        Long brigadeDeptId = getSectionDeptId(sectionDeptId);
        BigDecimal totalBrigadeSeizure = seizureReportMapper.selectBrigadeAverage(brigadeDeptId, startDate, endDate);
        Integer brigadeUserCount = seizureReportMapper.selectUserCountByBrigadeId(brigadeDeptId);
        BigDecimal brigadeAverage = (brigadeUserCount != null && brigadeUserCount > 0) ?
                totalBrigadeSeizure.divide(new BigDecimal(brigadeUserCount), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO;
        dto.setBrigadeAverage(brigadeAverage);

        // 全站平均数 = 全站查获总数 / 全站所有班组长和安检员数量
        Long stationDeptId = getStationDeptId(brigadeDeptId);
        BigDecimal totalStationSeizure = seizureReportMapper.selectStationAverage(stationDeptId, startDate, endDate);
        Integer stationUserCount = seizureReportMapper.selectUserCountByStationId(stationDeptId);
        BigDecimal stationAverage = (stationUserCount != null && stationUserCount > 0) ?
                totalStationSeizure.divide(new BigDecimal(stationUserCount), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO;
        dto.setStationAverage(stationAverage);

        // 设置排名信息
        // 班组排名：个人排名/全班组人数
        SeizureReportDTO.RankingInfo teamRanking = new SeizureReportDTO.RankingInfo();
        Integer teamCurrentRank = seizureReportMapper.selectSelfRanking(userId, deptId, "team", startDate, endDate);
        Integer teamTotalUsers = seizureReportMapper.selectUserCountByTeamId(deptId);
        teamRanking.setCurrentRank(ObjectUtil.isNotNull(teamCurrentRank) ? teamCurrentRank : teamTotalUsers);
        teamRanking.setTotalItems(teamTotalUsers);
        teamRanking.setRankingText((ObjectUtil.isNotNull(teamCurrentRank) ? teamCurrentRank : teamTotalUsers) + "/" + teamTotalUsers);

        // 科室排名：个人排名/全科安检员和班组长人数总和
        SeizureReportDTO.RankingInfo departmentRanking = new SeizureReportDTO.RankingInfo();
        Integer deptCurrentRank = seizureReportMapper.selectSelfRanking(userId, sectionDeptId, "department", startDate, endDate);
        Integer deptTotalUsers = seizureReportMapper.selectUserCountByDepartmentId(sectionDeptId);
        departmentRanking.setCurrentRank(ObjectUtil.isNotNull(deptCurrentRank) ? deptCurrentRank : deptTotalUsers);
        departmentRanking.setTotalItems(deptTotalUsers);
        departmentRanking.setRankingText((ObjectUtil.isNotNull(deptCurrentRank) ? deptCurrentRank : deptTotalUsers) + "/" + deptTotalUsers);

        // 大队排名：个人排名/全大队安检员和班组长人数总和
        SeizureReportDTO.RankingInfo brigadeRanking = new SeizureReportDTO.RankingInfo();
        Integer brigadeCurrentRank = seizureReportMapper.selectSelfRanking(userId, brigadeDeptId, "brigade", startDate, endDate);
        Integer brigadeTotalUsers = seizureReportMapper.selectUserCountByBrigadeId(brigadeDeptId);
        brigadeRanking.setCurrentRank(ObjectUtil.isNotNull(brigadeCurrentRank) ? brigadeCurrentRank : brigadeTotalUsers);
        brigadeRanking.setTotalItems(brigadeTotalUsers);
        brigadeRanking.setRankingText((ObjectUtil.isNotNull(brigadeCurrentRank) ? brigadeCurrentRank : brigadeTotalUsers) + "/" + brigadeTotalUsers);

        // 全站排名：个人排名/全站安检员和班组长人数总和
        SeizureReportDTO.RankingInfo stationRanking = new SeizureReportDTO.RankingInfo();
        Integer stationCurrentRank = seizureReportMapper.selectSelfRanking(userId, stationDeptId, "station", startDate, endDate);
        Integer stationTotalUsers = seizureReportMapper.selectUserCountByStationId(stationDeptId);
        stationRanking.setCurrentRank(ObjectUtil.isNotNull(stationCurrentRank) ? stationCurrentRank : stationTotalUsers);
        stationRanking.setTotalItems(stationTotalUsers);
        stationRanking.setRankingText((ObjectUtil.isNotNull(stationCurrentRank) ? stationCurrentRank : stationTotalUsers) + "/" + stationTotalUsers);

        // 设置各个排名信息
        dto.setTeamRanking(teamRanking);
        dto.setDepartmentRanking(departmentRanking);
        dto.setBrigadeRanking(brigadeRanking);
        dto.setStationRanking(stationRanking);

        // 设置待处理数据数量 - 草稿箱中数据数量
        FailedMatchItem failedMatchItem = new FailedMatchItem();
        // 设置查询条件为当前用户ID
        failedMatchItem.setUserId(userId);
        // 只查询未编辑的记录（app_edited=0或null）
        failedMatchItem.setAppEdited(false);

        List<FailedMatchItem> list = failedMatchItemService.selectFailedMatchItemList(failedMatchItem);
        int pendingCount = 0;
        if (CollectionUtil.isNotEmpty(list)) {
            pendingCount = list.size();
        }
        dto.setPendingCount(pendingCount);
    }


    /**
     * 处理班组长角色
     */
    private void handleTeamLeaderRoleForSpecificDTO(Long userId, Long deptId, java.util.Date startDate, java.util.Date endDate, TeamLeaderSeizureReportDTO dto) {
        //班组长查获总数
        BigDecimal teamSeizure = seizureReportMapper.selectTeamSeizure(deptId, startDate, endDate);
        dto.setTeamSeizure(teamSeizure);

        // 班组平均数 - 现在先获取总查获数，再除以人数
        BigDecimal totalTeamSeizure = seizureReportMapper.selectTeamAverage(deptId, startDate, endDate); // 这个方法现在返回总查获数
        Integer teamUserCount = seizureReportMapper.selectUserCountByTeamId(deptId); // 获取班组人数
        BigDecimal teamAverage = (teamUserCount != null && teamUserCount > 0) ?
                totalTeamSeizure.divide(new BigDecimal(teamUserCount), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO;
        dto.setTeamAverage(teamAverage);

        // 科室平均数 = 科室查获总数 / 科室下所有班组长和安检员数量
        Long sectionDeptId = getSectionDeptId(deptId);
        BigDecimal totalDepartmentSeizure = seizureReportMapper.selectDepartmentAverage(sectionDeptId, startDate, endDate);
        Integer deptUserCount = seizureReportMapper.selectUserCountByDepartmentId(sectionDeptId);
        BigDecimal sectionAverage = (deptUserCount != null && deptUserCount > 0) ?
                totalDepartmentSeizure.divide(new BigDecimal(deptUserCount), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO;
        dto.setDepartmentAverage(sectionAverage);

        // 大队平均数 = 大队查获总数 / 大队下所有科室下所有班组长和安检员数量
        Long brigadeDeptId = getSectionDeptId(sectionDeptId);
        BigDecimal totalBrigadeSeizure = seizureReportMapper.selectBrigadeAverage(brigadeDeptId, startDate, endDate);
        Integer brigadeUserCount = seizureReportMapper.selectUserCountByBrigadeId(brigadeDeptId);
        BigDecimal brigadeAverage = (brigadeUserCount != null && brigadeUserCount > 0) ?
                totalBrigadeSeizure.divide(new BigDecimal(brigadeUserCount), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO;
        dto.setBrigadeAverage(brigadeAverage);

        // 全站平均数 = 全站查获总数 / 全站所有班组长和安检员数量
        Long stationDeptId = getStationDeptId(brigadeDeptId);
        BigDecimal totalStationSeizure = seizureReportMapper.selectStationAverage(stationDeptId, startDate, endDate);
        Integer stationUserCount = seizureReportMapper.selectUserCountByStationId(stationDeptId);
        BigDecimal stationAverage = (stationUserCount != null && stationUserCount > 0) ?
                totalStationSeizure.divide(new BigDecimal(stationUserCount), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO;
        dto.setStationAverage(stationAverage);

        SeizureReportDTO.RankingInfo selfRanking = new SeizureReportDTO.RankingInfo();
        // 获取班组排名（在班组内的个人排名）
        Integer teamRank = seizureReportMapper.selectSelfRanking(userId, deptId, "team", startDate, endDate);
        selfRanking.setCurrentRank(teamRank);

        // 获取科室排名（班组在科室内的排名）
        SeizureReportDTO.RankingInfo deptRanking = new SeizureReportDTO.RankingInfo();
        Integer deptTeamRank = getTeamRankInDepartment(deptId, sectionDeptId, startDate, endDate);
        Integer deptTeamTotal = seizureReportMapper.selectTeamCountByDepartmentId(sectionDeptId);
        deptRanking.setCurrentRank(deptTeamRank);
        deptRanking.setTotalItems(deptTeamTotal);
        deptRanking.setRankingText(deptTeamRank + "/" + deptTeamTotal);

        // 获取大队排名（班组在大队内的排名）
        SeizureReportDTO.RankingInfo brigadeRanking = new SeizureReportDTO.RankingInfo();
        Integer deptBrigadeRank = getTeamRankInBrigade(deptId, brigadeDeptId, startDate, endDate);
        Integer deptBrigadeTotal = seizureReportMapper.selectTeamCountByBrigadeId(brigadeDeptId);
        brigadeRanking.setCurrentRank(deptBrigadeRank);
        brigadeRanking.setTotalItems(deptBrigadeTotal);
        brigadeRanking.setRankingText(deptBrigadeRank + "/" + deptBrigadeTotal);

        // 获取全站排名（班组在全站内的排名）
        SeizureReportDTO.RankingInfo stationRanking = new SeizureReportDTO.RankingInfo();
        Integer stationTeamRank = getTeamRankInStation(deptId, stationDeptId, startDate, endDate);
        Integer stationTeamTotal = seizureReportMapper.selectTeamCountByStationId(stationDeptId);
        stationRanking.setCurrentRank(stationTeamRank);
        stationRanking.setTotalItems(stationTeamTotal);
        stationRanking.setRankingText(stationTeamRank + "/" + stationTeamTotal);
        // 添加科室和全站排名信息
        dto.setDepartmentRanking(deptRanking);
        dto.setBrigadeRanking(brigadeRanking);
        dto.setStationRanking(stationRanking);

        // 设置待处理数据数量 - 草稿箱中数据数量
        FailedMatchItem failedMatchItem = new FailedMatchItem();
        // 设置查询条件为当前用户ID
        failedMatchItem.setUserId(userId);
        // 只查询未编辑的记录（app_edited=0或null）
        failedMatchItem.setAppEdited(false);

        List<FailedMatchItem> list = failedMatchItemService.selectFailedMatchItemList(failedMatchItem);
        int pendingCount = 0;
        if (CollectionUtil.isNotEmpty(list)) {
            pendingCount = list.size();
        }
        dto.setPendingCount(pendingCount);
    }


    /**
     * 处理科长角色
     */
    private void handleSectionLeaderRoleForSpecificDTO(Long userId, Long deptId, java.util.Date startDate, java.util.Date endDate, SectionMasterSeizureReportDTO dto) {
        // 待处理数据数量 - 查获审批流程中需要当前用户审批的任务数
        Integer pendingCount = seizureReportMapper.selectPendingCount(userId, null, null, null);
        dto.setPendingCount(pendingCount);

        // 科室平均数 = 科室查获总数 / 科室下所有班组长和安检员数量
        BigDecimal totalDepartmentSeizure = seizureReportMapper.selectDepartmentAverage(deptId, startDate, endDate);
        Integer deptUserCount = seizureReportMapper.selectUserCountByDepartmentId(deptId);
        BigDecimal sectionAverage = (deptUserCount != null && deptUserCount > 0) ?
                totalDepartmentSeizure.divide(new BigDecimal(deptUserCount), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO;
        dto.setDepartmentAverage(sectionAverage);

        // 大队平均数 = 大队查获总数 / 大队下所有科室下所有班组长和安检员数量
        Long brigadeDeptId = getStationDeptId(deptId);
        BigDecimal totalBrigadeSeizure = seizureReportMapper.selectBrigadeAverage(brigadeDeptId, startDate, endDate);
        Integer brigadeUserCount = seizureReportMapper.selectUserCountByBrigadeId(brigadeDeptId);
        BigDecimal brigadeAverage = (brigadeUserCount != null && brigadeUserCount > 0) ?
                totalBrigadeSeizure.divide(new BigDecimal(brigadeUserCount), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO;
        dto.setBrigadeAverage(brigadeAverage);

        // 全站平均数 = 全站查获总数 / 全站所有班组长和安检员数量
        Long stationDeptId = getStationDeptId(brigadeDeptId);
        BigDecimal totalStationSeizure = seizureReportMapper.selectStationAverage(stationDeptId, startDate, endDate);
        Integer stationUserCount = seizureReportMapper.selectUserCountByStationId(stationDeptId);
        BigDecimal stationAverage = (stationUserCount != null && stationUserCount > 0) ?
                totalStationSeizure.divide(new BigDecimal(stationUserCount), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO;
        dto.setStationAverage(stationAverage);

        // 科室查获总数
        BigDecimal sectionSeizure = seizureReportMapper.selectDepartmentSeizure(deptId, startDate, endDate);
        dto.setDepartmentSeizure(sectionSeizure);

        // 科室排名前三的班组
        List<SeizureReportDTO.TopThreeTeamItem> topThreeTeams = seizureReportMapper.selectTopThreeTeams(deptId, startDate, endDate);
        // 为每个团队设置排名
        for (int i = 0; i < topThreeTeams.size(); i++) {
            topThreeTeams.get(i).setRank(i + 1);
        }
        dto.setTopThreeTeams(topThreeTeams);

        // 设置全大队排名 - 科室排名/全大队科室数总和
        SeizureReportDTO.RankingInfo brigadeRanking = new SeizureReportDTO.RankingInfo();
        Integer deptInBrigadeRank = getDepartmentRankInBrigade(deptId, brigadeDeptId, startDate, endDate);
        Integer brigadeTotalDepts = seizureReportMapper.selectDepartmentCountByBrigadeId(brigadeDeptId);
        brigadeRanking.setCurrentRank(deptInBrigadeRank);
        brigadeRanking.setTotalItems(brigadeTotalDepts);
        brigadeRanking.setRankingText(deptInBrigadeRank + "/" + brigadeTotalDepts);
        dto.setBrigadeRanking(brigadeRanking);

        // 设置全站排名 - 科室排名/全站科室数总和
        SeizureReportDTO.RankingInfo stationRanking = new SeizureReportDTO.RankingInfo();
        Integer deptInStationRank = getDepartmentRankInStation(deptId, stationDeptId, startDate, endDate);
        Integer stationTotalDepts = seizureReportMapper.selectDepartmentCountByStationId(stationDeptId);
        stationRanking.setCurrentRank(deptInStationRank);
        stationRanking.setTotalItems(stationTotalDepts);
        stationRanking.setRankingText(deptInStationRank + "/" + stationTotalDepts);
        dto.setStationRanking(stationRanking);
    }

    /**
     * 处理经理和大队行政角色
     */
    private void handleBrigadeLeaderRoleForSpecificDTO(Long userId, Long deptId, java.util.Date startDate, java.util.Date endDate, BrigadeLeaderSeizureReportDTO dto) {
        // 大队平均数 = 大队查获总数 / 大队下所有科室下所有班组长和安检员数量
        BigDecimal totalBrigadeSeizure = seizureReportMapper.selectBrigadeAverage(deptId, startDate, endDate);
        Integer brigadeUserCount = seizureReportMapper.selectUserCountByBrigadeId(deptId);
        BigDecimal brigadeAverage = (brigadeUserCount != null && brigadeUserCount > 0) ?
                totalBrigadeSeizure.divide(new BigDecimal(brigadeUserCount), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO;
        dto.setBrigadeAverage(brigadeAverage);

        // 全站平均数 = 全站查获总数 / 全站所有班组长和安检员数量
        Long stationDeptId = getStationDeptId(deptId);
        BigDecimal totalStationSeizure = seizureReportMapper.selectStationAverage(stationDeptId, startDate, endDate);
        Integer stationUserCount = seizureReportMapper.selectUserCountByStationId(stationDeptId);
        BigDecimal stationAverage = (stationUserCount != null && stationUserCount > 0) ?
                totalStationSeizure.divide(new BigDecimal(stationUserCount), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO;
        dto.setStationAverage(stationAverage);

        // 大队查获总数
        BigDecimal brigadeSeizure = seizureReportMapper.selectBrigadeSeizure(deptId, startDate, endDate);
        dto.setBrigadeSeizure(brigadeSeizure);

        // 大队排名前三的主管
        List<SeizureReportDTO.TopThreeDepartmentItem> topThreeDepartment = seizureReportMapper.selectTopThreeDepartment(deptId, startDate, endDate);
        // 为每个团队设置排名
        for (int i = 0; i < topThreeDepartment.size(); i++) {
            topThreeDepartment.get(i).setRank(i + 1);
        }
        dto.setTopThreeDepartment(topThreeDepartment);

        // 设置全站排名 - 大队排名/全站大队数总和
        SeizureReportDTO.RankingInfo stationRanking = new SeizureReportDTO.RankingInfo();
        Integer deptInStationRank = getBrigadeRankInStation(deptId, stationDeptId, startDate, endDate);
        Integer stationTotalDepts = seizureReportMapper.selectBrigadeCountByStationId(stationDeptId);
        stationRanking.setCurrentRank(deptInStationRank);
        stationRanking.setTotalItems(stationTotalDepts);
        stationRanking.setRankingText(deptInStationRank + "/" + stationTotalDepts);
        dto.setStationRanking(stationRanking);
    }

    /**
     * 处理站长和质检员角色
     */
    private void handleStationLeaderRoleForSpecificDTO(Long userId, Long deptId, java.util.Date startDate, java.util.Date endDate, StationLeaderSeizureReportDTO dto) {
        // 全站查获总数
        BigDecimal totalStationSeizure = seizureReportMapper.selectTotalStationSeizure(deptId, startDate, endDate);
        dto.setTotalStationSeizure(totalStationSeizure);

        // 科室排名
//        List<SeizureReportDTO.DepartmentRankingItem> departmentRankings = seizureReportMapper.selectDepartmentRankings(deptId, startDate, endDate);
//        dto.setDepartmentRankings(departmentRankings);

        // 班组排名前三
        List<SeizureReportDTO.TeamRankingItem> topThreeTeamRankings = seizureReportMapper.selectTopThreeTeamRankings(deptId, startDate, endDate, "desc");
        dto.setTopThreeTeamRankings(topThreeTeamRankings);

        // 班组排名倒数前三
        List<SeizureReportDTO.TeamRankingItem> bottomThreeTeamRankings = seizureReportMapper.selectTopThreeTeamRankings(deptId, startDate, endDate, "asc");
        dto.setBotomThreeTeamRankings(bottomThreeTeamRankings);

        // 大队排名
        List<SeizureReportDTO.BrigadeRankingItem> brigadeRankings = seizureReportMapper.selectBrigadeRankings(deptId, startDate, endDate);
        dto.setBrigadeRankings(brigadeRankings);

        // 科室排名前三
        List<SeizureReportDTO.DepartmentRankingItem> topThreeDepartmentRankings = seizureReportMapper.selectTopThreeDepartmentRankings(deptId, startDate, endDate, "desc");
        dto.setTopThreeDepartmentRankings(topThreeDepartmentRankings);

        // 科室排名倒数前三
        List<SeizureReportDTO.DepartmentRankingItem> bottomThreeDepartmentRankings = seizureReportMapper.selectTopThreeDepartmentRankings(deptId, startDate, endDate, "asc");
        dto.setBotomThreeDepartmentRankings(bottomThreeDepartmentRankings);
    }

    /**
     * 获取班组在科室内的排名
     */
    private Integer getTeamRankInDepartment(Long teamId, Long departmentId, java.util.Date startDate, java.util.Date endDate) {
        // 获取科室下所有班组的排名
        List<SeizureReportDTO.TeamRankingItem> allTeamRankings = seizureReportMapper.selectAllTeamRankingsInDepartment(departmentId, startDate, endDate);

        // 找到指定班组的排名
        for (int i = 0; i < allTeamRankings.size(); i++) {
            SeizureReportDTO.TeamRankingItem item = allTeamRankings.get(i);
            // 由于TeamRankingItem的teamName只包含班组名称，我们需要通过其他方式匹配
            // 我们需要查询当前班组的名称以进行匹配
            SysDept currentTeam = sysDeptService.selectDeptById(teamId);
            if (currentTeam != null && item.getTeamName().equals(currentTeam.getDeptName())) {
                return i + 1; // 排名从1开始
            }
        }
        return allTeamRankings.size() + 1; // 如果未找到，则为最后一名
    }

    /**
     * 获取班组在大队内的排名
     */
    private Integer getTeamRankInBrigade(Long teamId, Long brigadetId, java.util.Date startDate, java.util.Date endDate) {
        // 获取科室下所有班组的排名
        List<SeizureReportDTO.TeamRankingItem> allBrigadeRankings = seizureReportMapper.selectAllTeamRankingsInBrigade(brigadetId, startDate, endDate);

        // 找到指定班组的排名
        for (int i = 0; i < allBrigadeRankings.size(); i++) {
            SeizureReportDTO.TeamRankingItem item = allBrigadeRankings.get(i);
            // 由于TeamRankingItem的teamName只包含班组名称，我们需要通过其他方式匹配
            // 我们需要查询当前班组的名称以进行匹配
            SysDept currentTeam = sysDeptService.selectDeptById(teamId);
            if (currentTeam != null && item.getTeamName().equals(currentTeam.getDeptName())) {
                return i + 1; // 排名从1开始
            }
        }
        return allBrigadeRankings.size() + 1; // 如果未找到，则为最后一名
    }

    /**
     * 获取班组在全站内的排名
     */
    private Integer getTeamRankInStation(Long teamId, Long stationId, java.util.Date startDate, java.util.Date endDate) {
        // 获取全站下所有班组的排名
        List<SeizureReportDTO.TeamRankingItem> allStationTeamRankings = seizureReportMapper.selectAllTeamRankingsInStation(stationId, startDate, endDate);

        // 找到指定班组的排名
        for (int i = 0; i < allStationTeamRankings.size(); i++) {
            SeizureReportDTO.TeamRankingItem item = allStationTeamRankings.get(i);
            // 由于TeamRankingItem的teamName包含科室名称+班组名称，我们需要通过其他方式匹配
            SysDept currentTeam = sysDeptService.selectDeptById(teamId);
            if (currentTeam != null) {
                // 检查是否包含班组名称
                if (item.getTeamName().contains(currentTeam.getDeptName())) {
                    return i + 1; // 排名从1开始
                }
            }
        }
        return allStationTeamRankings.size() + 1; // 如果未找到，则为最后一名
    }

    /**
     * 获取科室下所有班组的排名
     */
    private List<SeizureReportDTO.TeamRankingItem> getAllTeamRankingsInDepartment(Long departmentId, java.util.Date startDate, java.util.Date endDate) {
        return seizureReportMapper.selectAllTeamRankingsInDepartment(departmentId, startDate, endDate);
    }

    /**
     * 获取科室在全站内的排名
     */
    private Integer getDepartmentRankInStation(Long deptId, Long stationId, java.util.Date startDate, java.util.Date endDate) {
        // 获取全站下所有科室的排名
        List<SeizureReportDTO.DepartmentRankingItem> allStationDeptRankings = seizureReportMapper.selectAllDepartmentRankingsInStation(stationId, startDate, endDate);

        // 找到指定科室的排名
        SysDept currentDept = sysDeptService.selectDeptById(deptId);
        if (currentDept != null) {
            for (int i = 0; i < allStationDeptRankings.size(); i++) {
                SeizureReportDTO.DepartmentRankingItem item = allStationDeptRankings.get(i);
                if (item.getDepartmentName().equals(currentDept.getDeptName())) {
                    return i + 1; // 排名从1开始
                }
            }
        }
        return allStationDeptRankings.size() + 1; // 如果未找到，则为最后一名
    }

    /**
     * 获取大队在全站内的排名
     */
    private Integer getBrigadeRankInStation(Long deptId, Long stationId, java.util.Date startDate, java.util.Date endDate) {
        // 获取全站下所有科室的排名
        List<SeizureReportDTO.BrigadeRankingItem> allStationDeptRankings = seizureReportMapper.selectAllBrigadeRankingsInStation(stationId, startDate, endDate);

        // 找到指定科室的排名
        SysDept currentDept = sysDeptService.selectDeptById(deptId);
        if (currentDept != null) {
            for (int i = 0; i < allStationDeptRankings.size(); i++) {
                SeizureReportDTO.BrigadeRankingItem item = allStationDeptRankings.get(i);
                if (item.getBrigadeName().equals(currentDept.getDeptName())) {
                    return i + 1; // 排名从1开始
                }
            }
        }
        return allStationDeptRankings.size() + 1; // 如果未找到，则为最后一名
    }

    /**
     * 获取科室在全站内的排名
     */
    private Integer getDepartmentRankInBrigade(Long deptId, Long brigadeId, java.util.Date startDate, java.util.Date endDate) {
        // 获取全站下所有科室的排名
        List<SeizureReportDTO.DepartmentRankingItem> allStationDeptRankings = seizureReportMapper.selectAllDepartmentRankingsInBrigade(brigadeId, startDate, endDate);

        // 找到指定科室的排名
        SysDept currentDept = sysDeptService.selectDeptById(deptId);
        if (currentDept != null) {
            for (int i = 0; i < allStationDeptRankings.size(); i++) {
                SeizureReportDTO.DepartmentRankingItem item = allStationDeptRankings.get(i);
                if (item.getDepartmentName().equals(currentDept.getDeptName())) {
                    return i + 1; // 排名从1开始
                }
            }
        }
        return allStationDeptRankings.size() + 1; // 如果未找到，则为最后一名
    }

    /**
     * 获取全站下所有班组的排名
     */
    private List<SeizureReportDTO.TeamRankingItem> getAllTeamRankingsInStation(Long stationId, java.util.Date startDate, java.util.Date endDate) {
        return seizureReportMapper.selectAllTeamRankingsInStation(stationId, startDate, endDate);
    }

    /**
     * 获取科室部门ID（根据班组ID获取父级科室）
     */
    private Long getSectionDeptId(Long teamDeptId) {
        return seizureReportMapper.selectSectionDeptIdByTeamId(teamDeptId);
    }

    /**
     * 获取站点部门ID（根据部门ID获取站点级别ID）
     */
    private Long getStationDeptId(Long deptId) {
        return seizureReportMapper.selectStationDeptIdByDeptId(deptId);
    }

    /**
     * 获取数据权限
     *
     * @param userId 用户ID
     * @param deptId 部门ID
     * @return 数据权限结果
     */
    private DataPermissionResult getDataPermission(Long userId, Long deptId) {
        LoginUser loginUser = getLoginUser();
        if (loginUser == null) {
            return new DataPermissionResult(DataPermissionType.ALL, null);
        }

        // 假设我们通过某种方式获取到用户的角色
        List<SysRole> roles = loginUser.getUser().getRoles();
        List<String> roleKeys = roles.stream().map(SysRole::getRoleKey).collect(Collectors.toList());

        if (roleKeys.contains(RoleTypeEnum.SecurityCheck.getCode())) {
            return new DataPermissionResult(DataPermissionType.SELF, userId);
        } else if (roleKeys.contains(RoleTypeEnum.banzuzhang.getCode())) {
            return new DataPermissionResult(DataPermissionType.TEAM, deptId);
        } else if (roleKeys.contains(RoleTypeEnum.kezhang.getCode())) {
            return new DataPermissionResult(DataPermissionType.DEPARTMENT, deptId);
        } else if (roleKeys.contains(RoleTypeEnum.jingli.getCode()) || roleKeys.contains(RoleTypeEnum.xingzheng.getCode())) {
            return new DataPermissionResult(DataPermissionType.BRIGADE, deptId);
        } else if (roleKeys.contains(RoleTypeEnum.test.getCode()) || roleKeys.contains(RoleTypeEnum.zhijianke.getCode())) {
            return new DataPermissionResult(DataPermissionType.STATION, deptId);
        } else {
            return new DataPermissionResult(DataPermissionType.ALL, null);
        }
    }

    /**
     * 首页报表-查获上报数据
     *
     * @param dto 首页查询参数
     * @return 首页报表-查获上报数据
     */
    public SysHomeReportDetailDto seizureData(BaseLargeScreenQueryParamDto dto) {
        if (ObjUtil.isNull(dto.getUserId()) && ObjUtil.isNull(dto.getDeptId())) {
            throw new ServiceException("用户ID和部门ID不能同时为空");
        }
        // 默认筛选条件
        if (ObjUtil.isNull(dto.getStartDate()) && ObjUtil.isNull(dto.getEndDate()) && ObjUtil.isNull(dto.getSpecifiedDate())) {
            dto.setEndDate(LargeScreenDateUtils.getCurrentDate());
            dto.setStartDate(LargeScreenDateUtils.getDateBeforeYears(1));
        }
        SysHomeReportDetailDto result = new SysHomeReportDetailDto();
        // 全量数据
        List<SeizureLargeScreenHomePageItemDto> itemListAll = getSeizureLargeScreenHomePageItemDtoList(dto);

        List<SeizureLargeScreenHomePageItemDto> targetList;
        if (ObjUtil.isNotNull(dto.getUserId())) {
            SysUser sysUser = sysUserService.selectUserById(dto.getUserId());
            if (ObjUtil.isNull(sysUser)) {
                throw new ServiceException("【" + dto.getUserId() + "】用户不存在");
            }
            result.setId(sysUser.getUserId());
            result.setName(sysUser.getNickName());
            result.setType(HomePageQueryEnum.USER.getCode());
            targetList = itemListAll.stream().filter(item -> ObjUtil.equals(item.getId(), dto.getUserId())).collect(Collectors.toList());
        } else {
            SysDept sysDept = sysDeptService.selectDeptById(dto.getDeptId());
            if (ObjUtil.isNull(sysDept)) {
                throw new ServiceException("部门不存在");
            }
            result.setId(sysDept.getDeptId());
            result.setName(sysDept.getDeptName());
            result.setType(HomePageQueryEnum.DEPT.getCode());
            List<SysUser> sysUserList = sysUserService.selectUserListByRoleKeyAndDeptId(Arrays.asList(RoleTypeEnum.banzuzhang.getCode(), RoleTypeEnum.SecurityCheck.getCode()), sysDept.getDeptId());
            List<Long> userIdList = sysUserList.stream().map(SysUser::getUserId).collect(Collectors.toList());
            targetList = itemListAll.stream().filter(item -> userIdList.contains(item.getId())).collect(Collectors.toList());
        }
        List<BigDecimal> targetValueList = targetList.stream()
                .map(SeizureLargeScreenHomePageItemDto::getQuantity)
                .filter(Objects::nonNull)
                .sorted()
                .collect(Collectors.toList());
        if (CollUtil.isEmpty(targetValueList)) {
            result.setMaxNumber(BigDecimal.ZERO);
            result.setMinNumber(BigDecimal.ZERO);
            result.setTotalNumber(BigDecimal.ZERO);
            result.setAverageNumber(BigDecimal.ZERO);
            result.setMedianNumber(BigDecimal.ZERO);
            return result;
        }
        // 最大值
        result.setMaxNumber(targetValueList.get(targetValueList.size() - 1));
        // 最小值
        result.setMinNumber(targetValueList.get(0));
        // 总和
        BigDecimal sum = targetValueList.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        result.setTotalNumber(sum);
        // 总数
        int totalCount = targetValueList.size();
        // 平均值
        result.setAverageNumber(sum.divide(new BigDecimal(totalCount), 2, RoundingMode.HALF_UP));
        // 中位数
        int size = targetValueList.size();
        int middle = size / 2;
        if (size % 2 == 1) {
            result.setMedianNumber(targetValueList.get(middle));
        } else {
            result.setMedianNumber(targetValueList.get(middle - 1).add(targetValueList.get(middle)).divide(new BigDecimal(2), 2, RoundingMode.HALF_UP));
        }
        return result;
    }

    /**
     * 查获上报全量数据
     *
     * @param dto 查询参数
     * @return 查获上报全量数据
     */
    public List<SeizureLargeScreenHomePageItemDto> getSeizureLargeScreenHomePageItemDtoList(BaseLargeScreenQueryParamDto dto) {
        List<SeizureLargeScreenHomePageItemDto> result = new ArrayList<>();
        List<LargeScreenHomePageUserInfoSqlDto> userInfoListAll = sysUserService.homePageUserInfo();
        if (CollUtil.isEmpty(userInfoListAll)) {
            return Collections.emptyList();
        }
        List<ItemLargeScreenHomePageSeizureReportSqlDto> seizureReportListAll = seizureReportMapper.homePageSeizureReport(dto);
        if (CollUtil.isEmpty(seizureReportListAll)) {
            return Collections.emptyList();
        }
        Map<Long, BigDecimal> groupingBy = seizureReportListAll.stream().collect(Collectors.groupingBy(ItemLargeScreenHomePageSeizureReportSqlDto::getUserId, Collectors.reducing(BigDecimal.ZERO, ItemLargeScreenHomePageSeizureReportSqlDto::getQuantity, BigDecimal::add)));
        userInfoListAll.forEach(userInfoSqlDto -> {
            SeizureLargeScreenHomePageItemDto itemDto = new SeizureLargeScreenHomePageItemDto();
            itemDto.setId(userInfoSqlDto.getUserId());
            itemDto.setName(userInfoSqlDto.getNickName());
            itemDto.setQuantity(groupingBy.getOrDefault(userInfoSqlDto.getUserId(), BigDecimal.ZERO));
            result.add(itemDto);
        });
        return result;
    }

    /**
     * 查获上报大队级别全量数据
     *
     * @param dto 查询参数
     * @return 查获上报全量数据
     */
    public List<SeizureLargeScreenHomePageItemDto> getSeizureLargeScreenHomePinspectBrigadeIdList(BaseLargeScreenQueryParamDto dto) {
        List<SeizureLargeScreenHomePageItemDto> result = new ArrayList<>();
        List<LargeScreenHomePageUserInfoSqlDto> userInfoListAll = sysUserService.homePageUserInfo();
        if (CollUtil.isEmpty(userInfoListAll)) {
            return Collections.emptyList();
        }
        userInfoListAll = userInfoListAll.stream().filter(userInfoSqlDto -> userInfoSqlDto.getBrigadeId().equals(dto.getInspectBrigadeId())).collect(Collectors.toList());
        List<ItemLargeScreenHomePageSeizureReportSqlDto> seizureReportListAll = seizureReportMapper.homePageSeizureReportBrigadeId(dto);
        if (CollUtil.isEmpty(seizureReportListAll)) {
            return Collections.emptyList();
        }
        Map<Long, BigDecimal> groupingBy = seizureReportListAll.stream().collect(Collectors.groupingBy(ItemLargeScreenHomePageSeizureReportSqlDto::getUserId, Collectors.reducing(BigDecimal.ZERO, ItemLargeScreenHomePageSeizureReportSqlDto::getQuantity, BigDecimal::add)));
        userInfoListAll.forEach(userInfoSqlDto -> {
            SeizureLargeScreenHomePageItemDto itemDto = new SeizureLargeScreenHomePageItemDto();
            itemDto.setId(userInfoSqlDto.getUserId());
            itemDto.setName(userInfoSqlDto.getNickName());
            itemDto.setQuantity(groupingBy.getOrDefault(userInfoSqlDto.getUserId(), BigDecimal.ZERO));
            result.add(itemDto);
        });
        return result;
    }
}