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

import com.sundot.airport.blocked.domain.BlockedRate;
import com.sundot.airport.blocked.dto.BlockedRateScreenBrigadeDto;
import com.sundot.airport.blocked.dto.BlockedRateScreenT1Dto;
import com.sundot.airport.blocked.dto.BlockedRateScreenT2Dto;
import com.sundot.airport.blocked.mapper.BlockedRateMapper;
import com.sundot.airport.blocked.mapper.BlockedRateScreenMapper;
import com.sundot.airport.blocked.service.IBlockedRateScreenService;
import com.sundot.airport.common.core.domain.BlockedRateQueryParamDto;
import com.sundot.airport.common.core.domain.entity.SysDept;
import com.sundot.airport.common.utils.BlockedDateUtils;
import com.sundot.airport.system.service.ISysDeptService;
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.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 速率大屏Service业务层处理
 *
 * @author ruoyi
 * @date 2026-04-13
 */
@Service
public class BlockedRateScreenServiceImpl implements IBlockedRateScreenService {

    // 默认的精度
    private static final int SCALE = 2;
    // 默认的舍入模式
    private static final RoundingMode ROUNDING_MODE = RoundingMode.HALF_UP;
    // 目标大队名称列表
    private static final List<String> BRIGADE_NAMES = Arrays.asList("安检一大队", "安检二大队", "安检三大队");

    @Autowired
    private BlockedRateScreenMapper blockedRateScreenMapper;
    @Autowired
    private BlockedRateMapper blockedRateMapper;
    @Autowired
    private ISysDeptService sysDeptService;

    /**
     * T1速率统计数据
     *
     * @param dto 上行参数
     * @return 结果
     */
    @Override
    public List<BlockedRateScreenT1Dto> t1(BlockedRateQueryParamDto dto) {
        initDefaultDateRange(dto);
        List<Date> dateList = getDateList(dto);
        List<BlockedRate> blockedRateList = queryBlockedRateList(dto);
        Map<Date, List<BlockedRate>> dateGroupMap = groupByDate(blockedRateList);
        List<BlockedRateScreenT1Dto> result = new ArrayList<>();
        dateList.forEach(date -> {
            BlockedRateScreenT1Dto dtoItem = new BlockedRateScreenT1Dto();
            dtoItem.setStatDate(date);
            List<BlockedRate> dateData = dateGroupMap.getOrDefault(date, Collections.emptyList());
            dtoItem.setT1AAreaRatePeak(calculateAvg(dateData, BlockedRate::getT1AAreaRatePeak));
            dtoItem.setT1BAreaRatePeak(calculateAvg(dateData, BlockedRate::getT1BAreaRatePeak));
            result.add(dtoItem);
        });
        return result;
    }

    /**
     * T2速率统计数据
     *
     * @param dto 上行参数
     * @return 结果
     */
    @Override
    public List<BlockedRateScreenT2Dto> t2(BlockedRateQueryParamDto dto) {
        initDefaultDateRange(dto);
        List<Date> dateList = getDateList(dto);
        List<BlockedRate> blockedRateList = queryBlockedRateList(dto);
        Map<Date, List<BlockedRate>> dateGroupMap = groupByDate(blockedRateList);
        List<BlockedRateScreenT2Dto> result = new ArrayList<>();
        dateList.forEach(date -> {
            BlockedRateScreenT2Dto dtoItem = new BlockedRateScreenT2Dto();
            dtoItem.setStatDate(date);
            List<BlockedRate> dateData = dateGroupMap.getOrDefault(date, Collections.emptyList());
            dtoItem.setT2DomesticRatePeak(calculateAvg(dateData, BlockedRate::getT2DomesticRatePeak));
            dtoItem.setT2InternationalRatePeak(calculateAvg(dateData, BlockedRate::getT2InternationalRatePeak));
            result.add(dtoItem);
        });
        return result;
    }

    /**
     * 国内速率统计数据
     *
     * @param dto 上行参数
     * @return 结果
     */
    @Override
    public List<BlockedRateScreenBrigadeDto> domestic(BlockedRateQueryParamDto dto) {
        initDefaultDateRange(dto);
        List<Date> dateList = getDateList(dto);
        List<SysDept> targetDeptList = getTargetDeptList(dto);
        List<BlockedRate> blockedRateList = queryBlockedRateList(dto);
        Map<Date, List<BlockedRate>> dateGroupMap = groupByDate(blockedRateList);
        List<BlockedRateScreenBrigadeDto> result = new ArrayList<>();
        dateList.forEach(date -> {
            List<BlockedRate> dateData = dateGroupMap.getOrDefault(date, Collections.emptyList());
            targetDeptList.forEach(dept -> {
                BlockedRateScreenBrigadeDto dtoItem = new BlockedRateScreenBrigadeDto();
                dtoItem.setStatDate(date);
                dtoItem.setDutyBrigadeId(dept.getDeptId());
                dtoItem.setDutyBrigadeName(dept.getDeptName());
                List<BlockedRate> deptData = dateData.stream()
                        .filter(rate -> dept.getDeptId().equals(rate.getDutyBrigadeId()))
                        .collect(Collectors.toList());
                dtoItem.setAvgRatePeak(calculateAvg(deptData, BlockedRate::getTravelInspectionDomesticAvgRatePeak));
                result.add(dtoItem);
            });
        });
        return result;
    }

    /**
     * 国际速率统计数据
     *
     * @param dto 上行参数
     * @return 结果
     */
    @Override
    public List<BlockedRateScreenBrigadeDto> international(BlockedRateQueryParamDto dto) {
        initDefaultDateRange(dto);
        List<Date> dateList = getDateList(dto);
        List<SysDept> targetDeptList = getTargetDeptList(dto);
        List<BlockedRate> blockedRateList = queryBlockedRateList(dto);
        Map<Date, List<BlockedRate>> dateGroupMap = groupByDate(blockedRateList);
        List<BlockedRateScreenBrigadeDto> result = new ArrayList<>();
        dateList.forEach(date -> {
            List<BlockedRate> dateData = dateGroupMap.getOrDefault(date, Collections.emptyList());
            targetDeptList.forEach(dept -> {
                BlockedRateScreenBrigadeDto dtoItem = new BlockedRateScreenBrigadeDto();
                dtoItem.setStatDate(date);
                dtoItem.setDutyBrigadeId(dept.getDeptId());
                dtoItem.setDutyBrigadeName(dept.getDeptName());
                List<BlockedRate> deptData = dateData.stream()
                        .filter(rate -> dept.getDeptId().equals(rate.getDutyBrigadeId()))
                        .collect(Collectors.toList());
                dtoItem.setAvgRatePeak(calculateAvg(deptData, BlockedRate::getInternationalTransferAvgRatePeak));
                result.add(dtoItem);
            });
        });
        return result;
    }

    /**
     * 初始化默认日期范围
     *
     * @param dto 上行参数
     */
    private void initDefaultDateRange(BlockedRateQueryParamDto dto) {
        if (dto.getSpecifiedDate() == null && dto.getStartDate() == null && dto.getEndDate() == null) {
            dto.setStartDate(BlockedDateUtils.getFirstDayOfYear());
            dto.setEndDate(BlockedDateUtils.getCurrentDate());
        }
    }

    /**
     * 获取指定日期列表
     *
     * @param dto 上行参数
     * @return 日期列表
     */
    private List<Date> getDateList(BlockedRateQueryParamDto dto) {
        if (dto.getSpecifiedDate() != null) {
            return Collections.singletonList(dto.getSpecifiedDate());
        }
        return BlockedDateUtils.generateDateList(dto.getStartDate(), dto.getEndDate());
    }

    /**
     * 查询数据
     *
     * @param dto 上行参数
     * @return 列表
     */
    private List<BlockedRate> queryBlockedRateList(BlockedRateQueryParamDto dto) {
        BlockedRate query = new BlockedRate();
        query.setStatDate(dto.getSpecifiedDate());
        query.setStartDate(dto.getStartDate());
        query.setEndDate(dto.getEndDate());
        query.setDutyBrigadeId(dto.getBrigadeId());
        query.setDutyBrigadeName(dto.getBrigadeName());
        return blockedRateMapper.selectBlockedRateList(query);
    }

    /**
     * 按日期分组
     *
     * @param blockedRateList 数据列表
     * @return 分组结果
     */
    private Map<Date, List<BlockedRate>> groupByDate(List<BlockedRate> blockedRateList) {
        return blockedRateList.stream()
                .filter(rate -> rate.getStatDate() != null)
                .collect(Collectors.groupingBy(BlockedRate::getStatDate));
    }

    /**
     * 计算平均值
     *
     * @param dataList        数据列表
     * @param valueExtractor  值提取器
     * @return 平均值
     */
    private BigDecimal calculateAvg(List<BlockedRate> dataList, java.util.function.Function<BlockedRate, BigDecimal> valueExtractor) {
        List<BigDecimal> values = dataList.stream()
                .map(valueExtractor)
                .filter(val -> val != null && val.compareTo(BigDecimal.ZERO) != 0)
                .collect(Collectors.toList());
        if (values.isEmpty()) {
            return BigDecimal.ZERO;
        }
        BigDecimal sum = values.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        return sum.divide(BigDecimal.valueOf(values.size()), SCALE, ROUNDING_MODE);
    }

    /**
     * 获取指定部门列表
     *
     * @param dto 上行参数
     * @return 部门列表
     */
    private List<SysDept> getTargetDeptList(BlockedRateQueryParamDto dto) {
        if (dto.getBrigadeId() == null) {
            List<SysDept> deptListAll = sysDeptService.selectDeptInfoAll(new SysDept());
            return deptListAll.stream()
                    .filter(dept -> BRIGADE_NAMES.contains(dept.getDeptName()))
                    .collect(Collectors.toList());
        } else {
            return sysDeptService.selectDeptByIdList(Collections.singletonList(dto.getBrigadeId()));
        }
    }

}
