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

import com.sundot.airport.common.core.domain.entity.SysDept;
import com.sundot.airport.common.core.domain.entity.SysUser;
import com.sundot.airport.common.core.domain.model.LoginUser;
import com.sundot.airport.common.enums.MedalTypeEnum;
import com.sundot.airport.common.enums.RoleTypeEnum;
import com.sundot.airport.common.enums.portrait.UserType;
import com.sundot.airport.common.utils.DateUtils;
import com.sundot.airport.common.utils.SecurityUtils;
import com.sundot.airport.item.domain.dto.RankingQueryParamDto;
import com.sundot.airport.item.domain.dto.SeizureRankingDto;
import com.sundot.airport.item.domain.home.SeizureReportDTO;
import com.sundot.airport.item.mapper.SeizureReportMapper;
import com.sundot.airport.item.service.SeizureRankingService;
import com.sundot.airport.system.service.ISysDeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 查获排名服务实现类
 */
@Service
public class SeizureRankingServiceImpl implements SeizureRankingService {

    @Autowired
    private SeizureReportMapper seizureReportMapper;

    @Autowired
    private ISysDeptService sysDeptService;

    @Override
    public List<SeizureRankingDto> getRankingByRole(RankingQueryParamDto param) {
        List<String> roleKeys = addParam(param);
        if (param.getStartDate() == null) {
            // 设置时间范围
            setTimeRangeByType(param);
        }
        if (param.getEndDate() != null) {
            param.setEndDate(DateUtils.addSeconds(DateUtils.truncate(param.getEndDate(), Calendar.DAY_OF_MONTH), 86399));
        }
        if (roleKeys.contains(RoleTypeEnum.SecurityCheck.getCode())) {
            return getIndividualRanking(param);
        } else if (roleKeys.contains(RoleTypeEnum.banzuzhang.getCode())) {
            //个人和班组的切换
            if ("team".equals(param.getDataSource())) {
                return getTeamRanking(param);
            } else {
                return getIndividualRanking(param);
            }
        } else if (roleKeys.contains(RoleTypeEnum.kezhang.getCode())) {
            return getDepartmentRanking(param);
        } else if (roleKeys.contains(RoleTypeEnum.jingli.getCode()) || roleKeys.contains(RoleTypeEnum.xingzheng.getCode())) {
            return getBrigadeRanking(param);
        } else {
            return new ArrayList<>();
        }
    }

    /**
     * 添加参数
     */
    private List<String> addParam(RankingQueryParamDto param) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser currentUser = loginUser.getUser();
        Long userId = currentUser.getUserId();
        Long deptId = currentUser.getDeptId();
        param.setDeptId(deptId);
        param.setUserId(userId);
        // 获取用户角色列表
        List<String> roleKeys = currentUser.getRoles().stream()
                .map(role -> role.getRoleKey())
                .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);

        if (roleKeys.contains(RoleTypeEnum.SecurityCheck.getCode()) || roleKeys.contains(RoleTypeEnum.banzuzhang.getCode())) {
            Long sectionDeptId = getSectionDeptId(deptId);
            Long brigadeDeptId = getBrigadeDeptId(sectionDeptId);
            Long stationDeptId = getStationDeptId(brigadeDeptId);
            param.setTeamId(deptId);
            param.setDepartmentId(sectionDeptId);
            param.setBrigadeId(brigadeDeptId);
            param.setStationId(stationDeptId);
        } else if (roleKeys.contains(RoleTypeEnum.kezhang.getCode())) {
            Long brigadeDeptId = getBrigadeDeptId(deptId);
            Long stationDeptId = getStationDeptId(deptId);
            param.setDepartmentId(deptId);
            param.setBrigadeId(brigadeDeptId);
            param.setStationId(stationDeptId);
        } else if (roleKeys.contains(RoleTypeEnum.jingli.getCode()) || roleKeys.contains(RoleTypeEnum.xingzheng.getCode())) {
            Long stationDeptId = getStationDeptId(deptId);
            param.setBrigadeId(deptId);
            param.setStationId(stationDeptId);
        }
        return roleKeys;
    }

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

    /**
     * 获取大队部门ID（根据科室ID获取父级大队）
     */
    private Long getBrigadeDeptId(Long teamDeptId) {
        return seizureReportMapper.selectBrigadeDeptIdByDepartmentId(teamDeptId);
    }

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

    /**
     * 根据时间范围类型设置时间参数
     */
    private void setTimeRangeByType(RankingQueryParamDto param) {
        if (param.getTimeRangeType() == null) {
            // 默认近一年
            setDefaultTimeRange(param);
            return;
        }
        Date endDate = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);
        calendar.add(Calendar.DAY_OF_MONTH, -1); // 不包括今天
        endDate = calendar.getTime();
        Date startDate;
        switch (param.getTimeRangeType()) {
            case "last_week":
                calendar.add(Calendar.DAY_OF_MONTH, -7);
                startDate = calendar.getTime();
                break;
            case "last_month":
                calendar.add(Calendar.MONTH, -1);
                startDate = calendar.getTime();
                break;
            case "last_three_months":
                calendar.add(Calendar.MONTH, -3);
                startDate = calendar.getTime();
                break;
            case "last_half_year":
                calendar.add(Calendar.MONTH, -6);
                startDate = calendar.getTime();
                break;
            case "last_year":
            default:
                calendar.add(Calendar.YEAR, -1);
                startDate = calendar.getTime();
                break;
        }
        param.setStartDate(startDate);
        param.setEndDate(endDate);
    }

    /**
     * 设置默认时间范围（近一年，不包括今天）
     */
    private void setDefaultTimeRange(RankingQueryParamDto param) {
        Date endDate = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);
        calendar.add(Calendar.DAY_OF_MONTH, -1); // 不包括今天
        endDate = calendar.getTime();
        calendar.add(Calendar.YEAR, -1); // 近一年
        Date startDate = calendar.getTime();
        param.setStartDate(startDate);
        param.setEndDate(endDate);
    }

    /**
     * 获取个人排名
     */
    public List<SeizureRankingDto> getIndividualRanking(RankingQueryParamDto param) {
        SeizureReportDTO.RankingInfo stationRanking = new SeizureReportDTO.RankingInfo();
        Integer stationCurrentRank = seizureReportMapper.selectSelfRanking(param.getUserId(), param.getStationId(), "station", param.getStartDate(), param.getEndDate());
        Integer stationTotalUsers = seizureReportMapper.selectUserCountByStationId(param.getStationId());
        stationRanking.setCurrentRank(stationCurrentRank);
        if (stationCurrentRank == null) {
            stationRanking.setCurrentRank(stationTotalUsers);
        }
        stationRanking.setTotalItems(stationTotalUsers);
        // 处理排名
        return processRankingWithMedal(stationRanking, UserType.PERSONAL.getDescription(), param);
    }

    /**
     * 处理班组排名和奖牌逻辑
     */
    public List<SeizureRankingDto> getTeamRanking(RankingQueryParamDto param) {
        // 获取全站排名（班组在全站内的排名）
        SeizureReportDTO.RankingInfo stationRanking = new SeizureReportDTO.RankingInfo();
        Integer stationTeamRank = getTeamRankInStation(param.getDeptId(), param.getStationId(), param.getStartDate(), param.getEndDate());
        Integer stationTeamTotal = seizureReportMapper.selectTeamCountByStationId(param.getStationId());
        stationRanking.setCurrentRank(stationTeamRank);
        stationRanking.setTotalItems(stationTeamTotal);
        // 处理排名和奖牌逻辑
        return processRankingWithMedal(stationRanking, UserType.TEAM.getDescription(), param);
    }

    /**
     * 获取班组在全站内的排名
     */
    private Integer getTeamRankInStation(Long teamId, Long stationId, Date startDate, 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; // 如果未找到，则为最后一名
    }

    /**
     * 处理科室排名和奖牌逻辑
     */
    public List<SeizureRankingDto> getDepartmentRanking(RankingQueryParamDto param) {
        // 设置全站排名 - 科室排名/全站科室数总和
        SeizureReportDTO.RankingInfo stationRanking = new SeizureReportDTO.RankingInfo();
        Integer deptInStationRank = getDepartmentRankInStation(param.getDeptId(), param.getStationId(), param.getStartDate(), param.getEndDate());
        Integer stationTotalDepts = seizureReportMapper.selectDepartmentCountByStationId(param.getStationId());
        stationRanking.setCurrentRank(deptInStationRank);
        stationRanking.setTotalItems(stationTotalDepts);
        // 处理排名和奖牌逻辑
        return processRankingWithMedal(stationRanking, UserType.DEPARTMENT.getDescription(), param);
    }

    /**
     * 获取科室在全站内的排名
     */
    private Integer getDepartmentRankInStation(Long deptId, Long stationId, Date startDate, 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 List<SeizureRankingDto> processRankingWithMedal(SeizureReportDTO.RankingInfo rankingInfo, String userType, RankingQueryParamDto param) {
        if (rankingInfo == null || rankingInfo.getCurrentRank() == null) {
            return new ArrayList<>();
        }
        SeizureRankingDto dto = new SeizureRankingDto();
        dto.setRank(rankingInfo.getCurrentRank());
        dto.setUserType(userType);
        // 根据排名设置奖牌类型
        if (rankingInfo.getCurrentRank() != null) {
            if (rankingInfo.getCurrentRank() == 1) {
                dto.setMedalType(MedalTypeEnum.GOLD.getCode());
                dto.setMedalTypeDesc(MedalTypeEnum.GOLD.getDesc());
            } else if (rankingInfo.getCurrentRank() == 2) {
                dto.setMedalType(MedalTypeEnum.SILVER.getCode());
                dto.setMedalTypeDesc(MedalTypeEnum.SILVER.getDesc());
            } else if (rankingInfo.getCurrentRank() == 3) {
                dto.setMedalType(MedalTypeEnum.BRONZE.getCode());
                dto.setMedalTypeDesc(MedalTypeEnum.BRONZE.getDesc());
            } else if (rankingInfo.getTotalItems() != null &&
                    rankingInfo.getCurrentRank() >= rankingInfo.getTotalItems() - 2 &&
                    rankingInfo.getCurrentRank() <= rankingInfo.getTotalItems()) {
                // 后三名：最后一名哭脸红，倒数第二名哭脸橙，倒数第三名哭脸黄
                int positionFromEnd = rankingInfo.getTotalItems() - rankingInfo.getCurrentRank() + 1;
                if (positionFromEnd == 1) { // 最后一名
                    dto.setMedalType(MedalTypeEnum.CRY_RED.getCode());
                    dto.setMedalTypeDesc(MedalTypeEnum.CRY_RED.getDesc());
                } else if (positionFromEnd == 2) { // 倒数第二名
                    dto.setMedalType(MedalTypeEnum.CRY_ORANGE.getCode());
                    dto.setMedalTypeDesc(MedalTypeEnum.CRY_ORANGE.getDesc());
                } else if (positionFromEnd == 3) { // 倒数第三名
                    dto.setMedalType(MedalTypeEnum.CRY_YELLOW.getCode());
                    dto.setMedalTypeDesc(MedalTypeEnum.CRY_YELLOW.getDesc());
                }
            }
        }
        return Arrays.asList(dto);
    }

    /**
     * 获取大队在全站内的排名
     */
    public List<SeizureRankingDto> getBrigadeRanking(RankingQueryParamDto param) {
        // 设置全站排名 - 大队排名/全站大队数总和
        SeizureReportDTO.RankingInfo stationRanking = new SeizureReportDTO.RankingInfo();
        Integer deptInStationRank = getBrigadeRankInStation(param.getDeptId(), param.getStationId(), param.getStartDate(), param.getEndDate());
        Integer stationTotalDepts = seizureReportMapper.selectBrigadeCountByStationId(param.getStationId());
        stationRanking.setCurrentRank(deptInStationRank);
        stationRanking.setTotalItems(stationTotalDepts);
        // 处理排名和奖牌逻辑
        return processRankingWithMedal(stationRanking, UserType.BRIGADE.getDescription(), param);
    }

    /**
     * 获取大队在全站内的排名
     */
    private Integer getBrigadeRankInStation(Long deptId, Long stationId, Date startDate, 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; // 如果未找到，则为最后一名
    }

}