package com.hdkj.lt.bf.scheduler;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hdkj.lt.bf.entity.FhzgSeCapacityDaily;
import com.hdkj.lt.bf.entity.FhzgSeSnapshotDetail;
import com.hdkj.lt.bf.mapper.FhzgSeCapacityDailyMapper;
import com.hdkj.lt.bf.mapper.FhzgSeSnapshotDetailMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 供电能力日汇总定时任务
 * 每天凌晨1点，将昨天的断面明细聚合写入 fhzg_se_capacity_daily
 *
 * @author lsl
 * @since 2026-07-25
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class SeCapacityDailyScheduler {

    private final FhzgSeSnapshotDetailMapper snapshotDetailMapper;
    private final FhzgSeCapacityDailyMapper capacityDailyMapper;

    /**
     * 每天凌晨1点执行
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void aggregateYesterdayCapacity() {
        LocalDate yesterday = LocalDate.now().minusDays(1);
        log.info("[供电能力日汇总] 开始处理 {} 数据", yesterday);

        try {
            aggregateForDate(yesterday);
            log.info("[供电能力日汇总] {} 处理完成", yesterday);
        } catch (Exception e) {
            log.error("[供电能力日汇总] {} 处理失败", yesterday, e);
        }
    }

    /**
     * 聚合指定日期的断面数据到日汇总表
     */
    private void aggregateForDate(LocalDate date) {
        LocalDateTime startTime = date.atStartOfDay();
        LocalDateTime endTime = date.atTime(23, 59, 59);

        // 查昨天所有馈线断面
        LambdaQueryWrapper<FhzgSeSnapshotDetail> wrapper = new LambdaQueryWrapper<FhzgSeSnapshotDetail>()
                .eq(FhzgSeSnapshotDetail::getDeviceType, "feeder")
                .isNotNull(FhzgSeSnapshotDetail::getLoadRate)
                .ge(FhzgSeSnapshotDetail::getSnapshotTime, startTime)
                .le(FhzgSeSnapshotDetail::getSnapshotTime, endTime);

        List<FhzgSeSnapshotDetail> snapshots = snapshotDetailMapper.selectList(wrapper);

        if (snapshots.isEmpty()) {
            log.info("[供电能力日汇总] {} 无断面数据，跳过", date);
            return;
        }

        // 按馈线分组聚合
        Map<String, DailyAccumulator> accumulatorMap = new HashMap<>();
        for (FhzgSeSnapshotDetail s : snapshots) {
            String feederId = s.getFeederId();
            if (feederId == null) continue;

            DailyAccumulator acc = accumulatorMap.computeIfAbsent(feederId, k -> new DailyAccumulator());
            acc.countyId = s.getCountyId();
            acc.subsId = s.getSubsId();

            BigDecimal loadRate = s.getLoadRate();
            if (loadRate != null) {
                if (loadRate.compareTo(acc.maxLoadRate) > 0) {
                    acc.maxLoadRate = loadRate;
                }
                acc.sumLoadRate = acc.sumLoadRate.add(loadRate);
                acc.totalSnapshots++;
            }

            Integer status = s.getCurrentStatus();
            if (status != null) {
                if (status == 1) acc.heavyCount++;
                if (status == 2) acc.overloadCount++;
            }
        }

        // 先删当天已有数据（避免重复运行时叠加）
        LambdaQueryWrapper<FhzgSeCapacityDaily> deleteWrapper = new LambdaQueryWrapper<FhzgSeCapacityDaily>()
                .eq(FhzgSeCapacityDaily::getStatDate, date);
        capacityDailyMapper.delete(deleteWrapper);

        // 批量插入
        List<FhzgSeCapacityDaily> dailyRecords = new ArrayList<>();
        for (Map.Entry<String, DailyAccumulator> entry : accumulatorMap.entrySet()) {
            String feederId = entry.getKey();
            DailyAccumulator acc = entry.getValue();

            BigDecimal avgLoadRate = acc.totalSnapshots > 0
                    ? acc.sumLoadRate.divide(BigDecimal.valueOf(acc.totalSnapshots), 2, RoundingMode.HALF_UP)
                    : BigDecimal.ZERO;

            FhzgSeCapacityDaily daily = FhzgSeCapacityDaily.builder()
                    .statDate(date)
                    .feederId(feederId)
                    .feederName(null)
                    .countyId(acc.countyId)
                    .subsId(acc.subsId)
                    .maxLoadRate(acc.maxLoadRate)
                    .avgLoadRate(avgLoadRate)
                    .heavyCount(acc.heavyCount)
                    .overloadCount(acc.overloadCount)
                    .totalSnapshots(acc.totalSnapshots)
                    .createTime(LocalDateTime.now())
                    .updateTime(LocalDateTime.now())
                    .build();
            dailyRecords.add(daily);
        }

        // 批量插入
        for (FhzgSeCapacityDaily record : dailyRecords) {
            capacityDailyMapper.insert(record);
        }

        log.info("[供电能力日汇总] {} 处理完成: {} 条馈线日汇总", date, dailyRecords.size());
    }

    /**
     * 日聚合累加器
     */
    private static class DailyAccumulator {
        String countyId;
        String subsId;
        BigDecimal maxLoadRate = BigDecimal.ZERO;
        BigDecimal sumLoadRate = BigDecimal.ZERO;
        int heavyCount = 0;
        int overloadCount = 0;
        int totalSnapshots = 0;
    }
}