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

import com.sundot.airport.common.statistics.TimeDimensionParams;
import com.sundot.airport.common.statistics.TimeDimensionProcessor;
import com.sundot.airport.item.domain.dto.ChannelRankingStatsDTO;
import com.sundot.airport.item.domain.dto.ConcealmentPositionStatsDTO;
import com.sundot.airport.item.domain.dto.ItemCategoryStatsDTO;
import com.sundot.airport.item.domain.dto.PostCategoryStatsDTO;
import com.sundot.airport.item.domain.home.SeizureReportDTO;
import com.sundot.airport.item.mapper.ItemCategoryStatsMapper;
import com.sundot.airport.item.mapper.SeizureReportMapper;
import com.sundot.airport.item.service.IItemCategoryStatsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 查获物品分类统计服务实现类
 */
@Service
public class ItemCategoryStatsServiceImpl implements IItemCategoryStatsService {

    @Autowired
    private ItemCategoryStatsMapper itemCategoryStatsMapper;

    @Autowired
    private TimeDimensionProcessor timeDimensionProcessor;

    @Autowired
    private SeizureReportMapper seizureReportMapper;

    @Override
    public ItemCategoryStatsDTO getStationCategoryStats(TimeDimensionParams params, Long stationId) {
        // 计算时间范围
        TimeDimensionParams timeParams = timeDimensionProcessor.calculateTimeRange(params);

        ItemCategoryStatsDTO result = new ItemCategoryStatsDTO();
        result.setTimeDimension(this.getTimeDimensionLabel(params));
        result.setCurrentTimeLabel(this.getCurrentTimeLabel(params));

        // 查询分类统计数据
        List<ItemCategoryStatsDTO.CategoryStat> categoryStats =
                itemCategoryStatsMapper.selectStationCategoryStats(
                        stationId,
                        timeParams.getStartTime(),
                        timeParams.getEndTime(),
                        params.getBrigadeId(),
                        params.getDepartmentId(),
                        params.getTeamId(),
                        params.getUserId());

        // 查询总数量
        Long totalQuantity = itemCategoryStatsMapper.selectStationTotalQuantity(
                stationId,
                timeParams.getStartTime(),
                timeParams.getEndTime(),
                params.getBrigadeId(),
                params.getDepartmentId(),
                params.getTeamId(),
                params.getUserId());


        result.setCategoryStats(categoryStats);
        result.setTotalQuantity(new BigDecimal(totalQuantity));

        return result;
    }

    @Override
    public ConcealmentPositionStatsDTO getStationConcealmentPositionStats(TimeDimensionParams params, Long stationId) {
        // 计算时间范围
        TimeDimensionParams timeParams = timeDimensionProcessor.calculateTimeRange(params);

        ConcealmentPositionStatsDTO result = new ConcealmentPositionStatsDTO();
        result.setTimeDimension(this.getTimeDimensionLabel(params));
        result.setCurrentTimeLabel(this.getCurrentTimeLabel(params));

        // 查询部位统计数据
        List<ItemCategoryStatsDTO.CategoryStat> positionStats =
                itemCategoryStatsMapper.selectStationConcealmentPositionStats(
                        stationId,
                        timeParams.getStartTime(),
                        timeParams.getEndTime(),
                        params.getBrigadeId(),
                        params.getDepartmentId(),
                        params.getTeamId(),
                        params.getUserId());

        // 查询隐匿夹带总数量
        Long totalQuantity = itemCategoryStatsMapper.selectStationConcealmentTotalQuantity(
                stationId,
                timeParams.getStartTime(),
                timeParams.getEndTime(),
                params.getBrigadeId(),
                params.getDepartmentId(),
                params.getTeamId(),
                params.getUserId());

        // 转换为部位统计格式并计算占比
        List<ConcealmentPositionStatsDTO.PositionStat> convertedStats = positionStats.stream()
                .map(stat -> {
                    ConcealmentPositionStatsDTO.PositionStat positionStat = new ConcealmentPositionStatsDTO.PositionStat();
                    positionStat.setPositionCode(stat.getCategoryCodeOne());
                    positionStat.setPositionName(stat.getCategoryNameOne());
                    positionStat.setQuantity(BigDecimal.valueOf(stat.getQuantity().doubleValue()));

                    // 计算占比
                    if (totalQuantity > 0) {
                        BigDecimal percentage = BigDecimal.valueOf(stat.getQuantity().doubleValue())
                                .multiply(BigDecimal.valueOf(100))
                                .divide(BigDecimal.valueOf(totalQuantity.doubleValue()), 2, BigDecimal.ROUND_HALF_UP);
                        positionStat.setPercentage(percentage);
                    } else {
                        positionStat.setPercentage(BigDecimal.ZERO);
                    }

                    return positionStat;
                })
                .collect(java.util.stream.Collectors.toList());

        result.setPositionStats(convertedStats);
        result.setTotalQuantity(BigDecimal.valueOf(totalQuantity.doubleValue()));

        return result;
    }

    /**
     * 获取时间维度标签
     */
    private String getTimeDimensionLabel(TimeDimensionParams params) {
        if (params.getYear() != null) {
            if (params.getMonth() != null) {
                return "月度";
            } else if (params.getQuarter() != null) {
                return "季度";
            } else {
                return "年度";
            }
        }
        return "自定义";
    }

    @Override
    public PostCategoryStatsDTO getStationPostCategoryStats(TimeDimensionParams params, Long stationId) {
        // 计算时间范围
        TimeDimensionParams timeParams = timeDimensionProcessor.calculateTimeRange(params);

        PostCategoryStatsDTO result = new PostCategoryStatsDTO();
        result.setTimeDimension(this.getTimeDimensionLabel(params));
        result.setCurrentTimeLabel(this.getCurrentTimeLabel(params));

        // 查询岗位分类统计数据
        List<ItemCategoryStatsDTO.CategoryStat> postStats =
                itemCategoryStatsMapper.selectStationPostCategoryStats(
                        stationId,
                        timeParams.getStartTime(),
                        timeParams.getEndTime(),
                        params.getBrigadeId(),
                        params.getDepartmentId(),
                        params.getTeamId(),
                        params.getUserId());

        // 查询岗位分类总数量
        Long totalQuantity = itemCategoryStatsMapper.selectStationPostCategoryTotalQuantity(
                stationId,
                timeParams.getStartTime(),
                timeParams.getEndTime(),
                params.getBrigadeId(),
                params.getDepartmentId(),
                params.getTeamId(),
                params.getUserId());

        // 转换为岗位统计格式并计算占比
        List<PostCategoryStatsDTO.PostStat> convertedStats = postStats.stream()
                .map(stat -> {
                    PostCategoryStatsDTO.PostStat postStat = new PostCategoryStatsDTO.PostStat();
                    postStat.setPostCode(stat.getCategoryCodeOne());
                    postStat.setPostName(stat.getCategoryNameOne());
                    postStat.setQuantity(BigDecimal.valueOf(stat.getQuantity().doubleValue()));

                    // 计算占比
                    if (totalQuantity > 0) {
                        BigDecimal percentage = BigDecimal.valueOf(stat.getQuantity().doubleValue())
                                .multiply(BigDecimal.valueOf(100))
                                .divide(BigDecimal.valueOf(totalQuantity.doubleValue()), 2, BigDecimal.ROUND_HALF_UP);
                        postStat.setPercentage(percentage);
                    } else {
                        postStat.setPercentage(BigDecimal.ZERO);
                    }

                    return postStat;
                })
                .collect(java.util.stream.Collectors.toList());

        result.setPostStats(convertedStats);
        result.setTotalQuantity(BigDecimal.valueOf(totalQuantity.doubleValue()));

        return result;
    }

    @Override
    public ChannelRankingStatsDTO getStationChannelRankingStats(TimeDimensionParams params, Long stationId) {
        // 计算时间范围
        TimeDimensionParams timeParams = timeDimensionProcessor.calculateTimeRange(params);

        ChannelRankingStatsDTO result = new ChannelRankingStatsDTO();
        result.setTimeDimension(this.getTimeDimensionLabel(params));
        result.setCurrentTimeLabel(this.getCurrentTimeLabel(params));

        // 查询通道排名前五数据
        List<ChannelRankingStatsDTO.ChannelRankingItem> channelRankings =
                itemCategoryStatsMapper.selectTopFiveChannelRankings(
                        stationId,
                        timeParams.getStartTime(),
                        timeParams.getEndTime(),
                        params.getBrigadeId(),
                        params.getDepartmentId(),
                        params.getTeamId(),
                        params.getUserId());

        // 转换数据类型并设置查获数量
        List<ChannelRankingStatsDTO.ChannelRankingItem> convertedStats = channelRankings.stream()
                .map(item -> {
                    ChannelRankingStatsDTO.ChannelRankingItem rankingItem = new ChannelRankingStatsDTO.ChannelRankingItem();
                    rankingItem.setChannelName(item.getChannelName());
                    rankingItem.setSeizureQuantity(BigDecimal.valueOf(item.getSeizureQuantity().doubleValue()));
                    rankingItem.setRegionalName(item.getRegionalName());
                    rankingItem.setRanking(item.getRanking());
                    return rankingItem;
                })
                .collect(java.util.stream.Collectors.toList());

        result.setChannelRankings(convertedStats);

        return result;
    }

    @Override
    public List<SeizureReportDTO.BrigadeRankingItem> getBrigadeRanking(Long topSiteId, TimeDimensionParams params) {
        // 计算时间范围
        TimeDimensionParams timeParams = timeDimensionProcessor.calculateTimeRange(params);

        // 根据参数判断返回不同维度的排名
        if (params.getTeamId() != null) {
            // 传入班 ID，返回用户排名和占比
            List<SeizureReportDTO.UserRankingItem> userRankings = seizureReportMapper.selectUserRankingsByTeamId(
                    params.getTeamId(),
                    timeParams.getStartTime(),
                    timeParams.getEndTime());

            // 计算总查获数量
            BigDecimal totalSeizureQuantity = userRankings.stream()
                    .map(SeizureReportDTO.UserRankingItem::getSeizureCount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            // 计算排名和占比
            return convertUserRankingsToBrigadeRankings(userRankings, totalSeizureQuantity);
        } else if (params.getDepartmentId() != null) {
            // 传入科室 ID，返回班组排名和占比
            List<SeizureReportDTO.TeamRankingItem> teamRankings = seizureReportMapper.selectTeamRankingsByDepartmentId(
                    params.getDepartmentId(),
                    timeParams.getStartTime(),
                    timeParams.getEndTime());

            // 计算总查获数量
            BigDecimal totalSeizureQuantity = teamRankings.stream()
                    .map(SeizureReportDTO.TeamRankingItem::getSeizureCount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            // 计算排名和占比
            return convertTeamRankingsToBrigadeRankings(teamRankings, totalSeizureQuantity);
        } else if (params.getBrigadeId() != null) {
            // 传入大队 ID，返回科室排名和占比
            List<SeizureReportDTO.DepartmentRankingItem> departmentRankings = seizureReportMapper.selectDepartmentRankingsByBrigadeId(
                    params.getBrigadeId(),
                    timeParams.getStartTime(),
                    timeParams.getEndTime());

            // 计算总查获数量
            BigDecimal totalSeizureQuantity = departmentRankings.stream()
                    .map(SeizureReportDTO.DepartmentRankingItem::getSeizureCount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            // 计算排名和占比
            return convertDepartmentRankingsToBrigadeRankings(departmentRankings, totalSeizureQuantity);
        } else {
            // 返回大队排名和占比
            List<SeizureReportDTO.BrigadeRankingItem> brigadeRankings = seizureReportMapper.selectBrigadeRankings(
                    topSiteId,
                    timeParams.getStartTime(),
                    timeParams.getEndTime());

            // 计算总查获数量
            BigDecimal totalSeizureQuantity = brigadeRankings.stream()
                    .map(item -> item.getSeizureCount())
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            // 计算排名和占比
            for (int i = 0; i < brigadeRankings.size(); i++) {
                SeizureReportDTO.BrigadeRankingItem item = brigadeRankings.get(i);
                item.setCurrentRank(i + 1);
                item.setCurrentRatio(totalSeizureQuantity.compareTo(BigDecimal.ZERO) == 0 ?
                        BigDecimal.ZERO :
                        item.getSeizureCount().divide(totalSeizureQuantity, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)));
            }
            return brigadeRankings;
        }
    }

    /**
     * 将用户排名列表转换为大队排名列表格式
     */
    private List<SeizureReportDTO.BrigadeRankingItem> convertUserRankingsToBrigadeRankings(
            List<SeizureReportDTO.UserRankingItem> userRankings, BigDecimal totalSeizureQuantity) {

        List<SeizureReportDTO.BrigadeRankingItem> result = new ArrayList<>();
        for (int i = 0; i < userRankings.size(); i++) {
            SeizureReportDTO.UserRankingItem userItem = userRankings.get(i);
            SeizureReportDTO.BrigadeRankingItem deptItem = new SeizureReportDTO.BrigadeRankingItem();
            deptItem.setBrigadeName(userItem.getUserName());
            deptItem.setSeizureCount(userItem.getSeizureCount());
            deptItem.setCurrentRank(i + 1);
            deptItem.setCurrentRatio(totalSeizureQuantity.compareTo(BigDecimal.ZERO) == 0 ?
                    BigDecimal.ZERO :
                    userItem.getSeizureCount().divide(totalSeizureQuantity, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)));
            result.add(deptItem);
        }
        return result;
    }

    /**
     * 将班组排名列表转换为大队排名列表格式
     */
    private List<SeizureReportDTO.BrigadeRankingItem> convertTeamRankingsToBrigadeRankings(
            List<SeizureReportDTO.TeamRankingItem> teamRankings, BigDecimal totalSeizureQuantity) {

        List<SeizureReportDTO.BrigadeRankingItem> result = new ArrayList<>();
        for (int i = 0; i < teamRankings.size(); i++) {
            SeizureReportDTO.TeamRankingItem teamItem = teamRankings.get(i);
            SeizureReportDTO.BrigadeRankingItem deptItem = new SeizureReportDTO.BrigadeRankingItem();
            deptItem.setBrigadeName(teamItem.getTeamName());
            deptItem.setSeizureCount(teamItem.getSeizureCount());
            deptItem.setCurrentRank(i + 1);
            deptItem.setCurrentRatio(totalSeizureQuantity.compareTo(BigDecimal.ZERO) == 0 ?
                    BigDecimal.ZERO :
                    teamItem.getSeizureCount().divide(totalSeizureQuantity, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)));
            result.add(deptItem);
        }
        return result;
    }

    /**
     * 将科室排名列表转换为大队排名列表格式
     */
    private List<SeizureReportDTO.BrigadeRankingItem> convertDepartmentRankingsToBrigadeRankings(
            List<SeizureReportDTO.DepartmentRankingItem> departmentRankings, BigDecimal totalSeizureQuantity) {

        List<SeizureReportDTO.BrigadeRankingItem> result = new ArrayList<>();
        for (int i = 0; i < departmentRankings.size(); i++) {
            SeizureReportDTO.DepartmentRankingItem teamItem = departmentRankings.get(i);
            SeizureReportDTO.BrigadeRankingItem deptItem = new SeizureReportDTO.BrigadeRankingItem();
            deptItem.setBrigadeName(teamItem.getDepartmentName());
            deptItem.setSeizureCount(teamItem.getSeizureCount());
            deptItem.setCurrentRank(i + 1);
            deptItem.setCurrentRatio(totalSeizureQuantity.compareTo(BigDecimal.ZERO) == 0 ?
                    BigDecimal.ZERO :
                    teamItem.getSeizureCount().divide(totalSeizureQuantity, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)));
            result.add(deptItem);
        }
        return result;
    }

    /**
     * 获取当前时间标签
     */
    private String getCurrentTimeLabel(TimeDimensionParams params) {
        if (params.getYear() != null) {
            if (params.getMonth() != null) {
                return params.getYear() + "年" + params.getMonth() + "月";
            } else if (params.getQuarter() != null) {
                return params.getYear() + "年第" + params.getQuarter() + "季度";
            } else {
                return params.getYear() + "年";
            }
        }
        if (params.getStartTime() != null && params.getEndTime() != null) {
            return params.getStartTime() + "至" + params.getEndTime();
        }
        return "当前期间";
    }
}