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

import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sundot.airport.common.utils.DateUtils;
import com.sundot.airport.ledger.domain.OperationStationHourlyThroughput;
import com.sundot.airport.ledger.domain.vo.AreaFlowVO;
import com.sundot.airport.ledger.domain.vo.LaneThroughputResVO;
import com.sundot.airport.ledger.domain.vo.StationHourlyThroughputGroupResVO;
import com.sundot.airport.ledger.domain.vo.StationHourlyThroughputVO;
import com.sundot.airport.ledger.mapper.OperationStationHourlyThroughputMapper;
import com.sundot.airport.ledger.service.IOperationStationHourlyThroughputService;
import com.sundot.airport.system.domain.BasePosition;
import com.sundot.airport.system.mapper.BasePositionMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 站级时间段别总过检Service业务层处理
 */
@Slf4j
@Service
public class OperationStationHourlyThroughputServiceImpl extends ServiceImpl<OperationStationHourlyThroughputMapper, OperationStationHourlyThroughput> implements IOperationStationHourlyThroughputService {

    @Autowired
    private OperationStationHourlyThroughputMapper operationStationHourlyThroughputMapper;
    @Autowired
    private BasePositionMapper basePositionMapper;

    /**
     * 查询站级时间段别总过检列表
     *
     * @param operationStationHourlyThroughput 站级时间段别总过检
     * @return 站级时间段别总过检
     */
    @Override
    public List<OperationStationHourlyThroughput> selectOperationStationHourlyThroughputList(OperationStationHourlyThroughput operationStationHourlyThroughput) {
        return operationStationHourlyThroughputMapper.selectOperationStationHourlyThroughputList(operationStationHourlyThroughput);
    }

    /**
     * 新增站级时间段别总过检
     *
     * @param operationStationHourlyThroughput 站级时间段别总过检
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertOperationStationHourlyThroughput(OperationStationHourlyThroughput operationStationHourlyThroughput) {
        operationStationHourlyThroughput.setCreateTime(DateUtils.getNowDate());
        return operationStationHourlyThroughputMapper.insert(operationStationHourlyThroughput);
    }

    /**
     * 修改站级时间段别总过检
     *
     * @param operationStationHourlyThroughput 站级时间段别总过检
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateOperationStationHourlyThroughput(OperationStationHourlyThroughput operationStationHourlyThroughput) {
        operationStationHourlyThroughput.setUpdateTime(DateUtils.getNowDate());
        return operationStationHourlyThroughputMapper.updateById(operationStationHourlyThroughput);
    }

    /**
     * 批量删除站级时间段别总过检
     *
     * @param ids 需要删除的站级时间段别总过检主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteOperationStationHourlyThroughputByIds(Long[] ids) {
        return operationStationHourlyThroughputMapper.deleteBatchIds(java.util.Arrays.asList(ids));
    }

    /**
     * 删除站级时间段别总过检信息
     *
     * @param id 站级时间段别总过检主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteOperationStationHourlyThroughputById(Long id) {
        return operationStationHourlyThroughputMapper.deleteById(id);
    }

    /**
     * 功能描述：统计站级时间段人流量
     *
     * @return List<StationHourlyThroughputGroupResVO> 站级时间段人流量
     * @method countStationHourlyThroughput
     * @author PanHu Sun
     * @date 2026/5/19 16:46
     */
    @Override
    public List<StationHourlyThroughputGroupResVO> countStationHourlyThroughput() {
        List<StationHourlyThroughputVO> stationHourlyThroughputList = this.baseMapper.countStationHourlyThroughput();
        stationHourlyThroughputList = CollUtil.emptyIfNull(stationHourlyThroughputList);

        log.info("SQL查询返回数据条数: {}", stationHourlyThroughputList.size());
        if (!stationHourlyThroughputList.isEmpty()) {
            log.info("SQL查询返回的时间点列表: {}", 
                    stationHourlyThroughputList.stream()
                            .map(StationHourlyThroughputVO::getHourOfDay)
                            .distinct()
                            .collect(Collectors.toList()));
        }

        Map<Long, BasePosition> areaInfoMap = Maps.newHashMap();
        // 1. 预处理：获取区域名称
        Set<Long> areaIds = stationHourlyThroughputList.stream()
                .filter(station -> Objects.nonNull(station.getAreaId()))
                .map(StationHourlyThroughputVO::getAreaId)
                .collect(Collectors.toSet());
        if (CollUtil.isNotEmpty(areaIds)) {
            // 查询base_position表获取区域名称
            List<BasePosition> basePositions = basePositionMapper.selectPositionListByIds(areaIds);
            // 将basePositions转成map，key是id，value是BasePosition
            areaInfoMap = CollUtil.emptyIfNull(basePositions).stream().collect(Collectors.toMap(BasePosition::getId, v -> v));
        }

        // 2. 按时间点分组
        Map<String, List<StationHourlyThroughputVO>> hourGroupMap = stationHourlyThroughputList.stream()
                .collect(Collectors.groupingBy(StationHourlyThroughputVO::getHourOfDay));

        // 3. 生成近24个具体时间点（从当前时间向前推24小时）
        List<String> last24Hours = this.generateLast24Hours();
        
        log.info("需要补齐的24个时间点: {}", last24Hours);

        Map<Long, BasePosition> finalAreaInfoMap = areaInfoMap;
        
        // 4. 补齐24个时间点数据
        List<StationHourlyThroughputGroupResVO> resultList = Lists.newArrayList();
        for (String hourTime : last24Hours) {
            // 处理日期 转换hourTime格式的日期，例如：2026-05-21 00:00转成0:00，2026-05-21 01:00转成01:00，2026-05-21 11:00转成11:00
            // 提取小时和分钟部分（去掉日期）
            String hourOnly = this.extractHourAndMinute(hourTime);

            if (hourGroupMap.containsKey(hourTime)) {
                // 存在数据的时间点，正常组装
                List<StationHourlyThroughputVO> hourDataList = hourGroupMap.get(hourTime);
                
                List<AreaFlowVO> areaList = hourDataList.stream().map(stats -> {
                    BasePosition basePosition = finalAreaInfoMap.get(stats.getAreaId());
                    AreaFlowVO areaFlowVO = new AreaFlowVO();
                    areaFlowVO.setAreaId(stats.getAreaId());
                    areaFlowVO.setAreaName(Objects.nonNull(basePosition) ? basePosition.getName() : "");
                    areaFlowVO.setAreaFlow(stats.getAreaFlow());
                    return areaFlowVO;
                }).collect(Collectors.toList());

                // 补充缺失的区域信息
                if (CollUtil.isEmpty(areaList)){
                    areaInfoMap.forEach((id, basePosition) -> {
                        areaList.add(new AreaFlowVO(id, basePosition.getName(), 0));
                    });
                } else {
                    if (areaList.size() != areaInfoMap.size()) {
                        areaInfoMap.forEach((id, basePosition) -> {
                            AreaFlowVO newAreaFlow = areaList.stream().filter(areaFlowVO -> areaFlowVO.getAreaId().equals(id)).findFirst().orElse(null);
                            if (Objects.isNull(newAreaFlow)) {
                                areaList.add(new AreaFlowVO(id, basePosition.getName(), 0));
                            }
                        });
                    }
                }

                // 按区域id升序排序
                if (CollUtil.isNotEmpty(areaList)){
                    areaList.sort(Comparator.comparing(AreaFlowVO::getAreaId));
                }

                StationHourlyThroughputGroupResVO groupVO = new StationHourlyThroughputGroupResVO();
                groupVO.setHourOfDay(hourTime);
                groupVO.setHour(hourOnly);
                groupVO.setTotalHourFlow(hourDataList.get(0).getTotalHourFlow());
                groupVO.setAreaList(areaList);
                resultList.add(groupVO);
            } else {
                List<AreaFlowVO> areaList = Lists.newArrayList();
                areaInfoMap.forEach((id, basePosition) -> {
                    areaList.add(new AreaFlowVO(id, basePosition.getName(), 0));
                });

                // 按区域id升序排序
                if (CollUtil.isNotEmpty(areaList)){
                    areaList.sort(Comparator.comparing(AreaFlowVO::getAreaId));
                }

                // 缺失的时间点，补充空数据
                StationHourlyThroughputGroupResVO emptyVO = new StationHourlyThroughputGroupResVO();
                emptyVO.setHourOfDay(hourTime);
                emptyVO.setHour(hourOnly);
                emptyVO.setTotalHourFlow(0);
                emptyVO.setAreaList(areaList);
                resultList.add(emptyVO);
            }
        }
        
        log.info("补齐后返回的总时间点数: {}", resultList.size());
        return resultList;
    }
    
    /**
     * 生成近24个具体时间点（从当前时间向前推24小时）
     * 格式：yyyy-MM-dd HH:00
     */
    private List<String> generateLast24Hours() {
        List<String> hours = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        
        // 从当前小时向前推23小时，共24个时间点
        for (int i = 23; i >= 0; i--) {
            Calendar cal = (Calendar) calendar.clone();
            cal.add(Calendar.HOUR_OF_DAY, -i);
            
            String hourTime = String.format("%04d-%02d-%02d %02d:00",
                    cal.get(Calendar.YEAR),
                    cal.get(Calendar.MONTH) + 1,
                    cal.get(Calendar.DAY_OF_MONTH),
                    cal.get(Calendar.HOUR_OF_DAY));
            hours.add(hourTime);
        }
        
        return hours;
    }
    
    /**
     * 从完整日期时间中提取小时和分钟部分
     * 例如：2026-05-21 00:00 → 0:00
     *      2026-05-21 01:00 → 01:00
     *      2026-05-21 11:00 → 11:00
     * 
     * @param hourTime 完整日期时间字符串（格式：yyyy-MM-dd HH:00）
     * @return 小时和分钟字符串（格式：H:00 或 HH:00）
     */
    private String extractHourAndMinute(String hourTime) {
        if (hourTime == null || hourTime.trim().isEmpty()) {
            return "";
        }
        
        // 按空格分割，取时间部分
        String[] parts = hourTime.split(" ");
        if (parts.length < 2) {
            return hourTime;
        }
        
        String timePart = parts[1]; // 获取 "00:00" 部分
        
        // 去掉小时的前导0（如果有的话）
        String[] timeComponents = timePart.split(":");
        if (timeComponents.length >= 2) {
            int hour = Integer.parseInt(timeComponents[0]);
            String minute = timeComponents[1];
            return hour + ":" + minute;
        }
        
        return timePart;
    }
}
