package com.hdkj.lt.bf.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hdkj.fhzg.optimization.response.FeederGroupTreeNode;
import com.hdkj.lt.bf.application.FeederGroupApplication;
import com.hdkj.lt.bf.entity.SjztPwwyyqxtPrmPdrOutageMvDs;
import com.hdkj.lt.bf.entity.dto.OutageAggregationDTO;
import com.hdkj.lt.bf.entity.dto.TodayOutageData;
import com.hdkj.lt.bf.mapper.GridPdOutageEventBaseMapper;
import com.hdkj.lt.bf.mapper.SjztPwwyyqxtPrmPdrOutageMvDsMapper;
import com.hdkj.lt.bf.service.SjztPwwyyqxtPrmPdrOutageMvDsService;
import com.hdkj.lt.core.bizms.modle.po.GridPdOutageEventBase;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

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

/**
* @author lenovo
* @description 针对表【sjzt_pwwyyqxt_prm_pdr_outage_mv_ds(un4113_02_pwwyyqxt_prm_pdr_outage_mv_ds)】的数据库操作Service实现
* @createDate 2026-07-18 14:32:38
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class SjztPwwyyqxtPrmPdrOutageMvDsServiceImpl extends ServiceImpl<SjztPwwyyqxtPrmPdrOutageMvDsMapper, SjztPwwyyqxtPrmPdrOutageMvDs>
    implements SjztPwwyyqxtPrmPdrOutageMvDsService{

    private final SjztPwwyyqxtPrmPdrOutageMvDsMapper prmPdrOutageMvDsMapper;
    private final FeederGroupApplication feederGroupApplication;
    private final GridPdOutageEventBaseMapper gridPdOutageEventBaseMapper;

    // ============================================================
    // T-2 历史数据（sjzt_pwwyyqxt_prm_pdr_outage_mv_ds）
    // ============================================================

    @Override
        public BigDecimal selectStaticOutageDurationHoursHouseholds(List<String> feederNameList) {
            LocalDateTime startOfMonth = LocalDate.now().withDayOfMonth(1).atStartOfDay();
            LocalDateTime endOfToday = LocalDateTime.of(LocalDate.now(), java.time.LocalTime.MAX);
        return prmPdrOutageMvDsMapper.selectStaticOutageDurationHoursHouseholds(feederNameList, startOfMonth, endOfToday);
    }

    @Override
    public TodayOutageData getOutageDurationHoursHouseholds(String id, Integer type,
                                                             LocalDateTime startTime, LocalDateTime endTime) {
        List<FeederGroupTreeNode> tree = feederGroupApplication.getFeederGroupTree();
        List<String> feederNames = new ArrayList<>();

        if (type == 4) {
            FeederGroupTreeNode node = findNodeRecursively(tree, 4, id);
            if (node != null) {
                feederNames.add(node.getName());
            }
        } else {
            FeederGroupTreeNode node = findNodeRecursively(tree, type, id);
            if (node != null && node.getChildren() != null) {
                collectNodesByType(node.getChildren(), feederNames);
            }
        }

        if (feederNames.isEmpty()) {
            log.warn("未找到馈线名列表 id={}, type={}", id, type);
            return TodayOutageData.builder()
                    .totalHouseholds(BigDecimal.ZERO)
                    .avgDurationHours(BigDecimal.ZERO)
                    .build();
        }

        OutageAggregationDTO stats = prmPdrOutageMvDsMapper.selectOutageAggregation(feederNames, startTime, endTime);

        BigDecimal totalHC = stats != null ? stats.getTotalHouseholds() : BigDecimal.ZERO;
        BigDecimal totalUsers = stats != null ? stats.getTotalAffectedUsers() : BigDecimal.ZERO;

        // 平均停电时长(小时) = 总时户数 / 总影响用户数
        BigDecimal avgDuration = (totalUsers.compareTo(BigDecimal.ZERO) > 0)
                ? totalHC.divide(totalUsers, 2, RoundingMode.HALF_UP)
                : BigDecimal.ZERO;

        return TodayOutageData.builder()
                .totalHouseholds(totalHC)
                .avgDurationHours(avgDuration)
                .build();
    }

    // ============================================================
    // 当日实时数据（grid_pd_outage_event_base）
    // ============================================================

    @Override
    public TodayOutageData getTodayOutageData(String id, Integer type) {
        LocalDateTime todayStart = LocalDate.now().atStartOfDay();
        LocalDateTime tomorrowStart = LocalDate.now().plusDays(1).atStartOfDay();

        LambdaQueryWrapper<GridPdOutageEventBase> wrapper = new LambdaQueryWrapper<GridPdOutageEventBase>()
                .ge(GridPdOutageEventBase::getBeginTime, todayStart)
                .lt(GridPdOutageEventBase::getBeginTime, tomorrowStart);

        if (type == 2) {
            wrapper.eq(GridPdOutageEventBase::getCountyId, id);
        } else if (type == 3) {
            wrapper.eq(GridPdOutageEventBase::getRdtSubsId, id);
        } else if (type == 4) {
            wrapper.eq(GridPdOutageEventBase::getRdtFeederId, id);
        } else {
            log.warn("不支持的节点类型 type={}", type);
            return TodayOutageData.builder()
                    .totalHouseholds(BigDecimal.ZERO)
                    .avgDurationHours(BigDecimal.ZERO)
                    .build();
        }

        List<GridPdOutageEventBase> events = gridPdOutageEventBaseMapper.selectList(wrapper);

        BigDecimal totalHouseholds = BigDecimal.ZERO;
        BigDecimal totalAffectedUsers = BigDecimal.ZERO;

        for (GridPdOutageEventBase event : events) {
            // 累计停电时户数
            if (event.getHouseholdCnt() != null) {
                try {
                    totalHouseholds = totalHouseholds.add(new BigDecimal(event.getHouseholdCnt()));
                } catch (NumberFormatException e) {
                    log.warn("householdCnt 格式异常: {}", event.getHouseholdCnt());
                }
            }
            // 累计停电影响用户数（分母）
            if (event.getAffectedConsCnt() != null) {
                totalAffectedUsers = totalAffectedUsers.add(new BigDecimal(event.getAffectedConsCnt()));
            }
        }

        // 平均停电时长(小时) = 总时户数 / 总影响用户数
        BigDecimal avgDurationHours = (totalAffectedUsers.compareTo(BigDecimal.ZERO) > 0)
                ? totalHouseholds.divide(totalAffectedUsers, 2, RoundingMode.HALF_UP)
                : BigDecimal.ZERO;

        return TodayOutageData.builder()
                .totalHouseholds(totalHouseholds)
                .avgDurationHours(avgDurationHours)
                .build();
    }

    // ============================================================
    // 树递归辅助
    // ============================================================

    private FeederGroupTreeNode findNodeRecursively(List<FeederGroupTreeNode> nodes, int nodeType, String targetId) {
        if (nodes == null || nodes.isEmpty()) return null;
        for (FeederGroupTreeNode node : nodes) {
            if (node.getType() == nodeType && targetId.equals(node.getId())) {
                return node;
            }
            if (node.getChildren() != null && !node.getChildren().isEmpty()) {
                FeederGroupTreeNode found = findNodeRecursively(node.getChildren(), nodeType, targetId);
                if (found != null) return found;
            }
        }
        return null;
    }

    private void collectNodesByType(List<FeederGroupTreeNode> nodes, List<String> collector) {
        if (nodes == null || nodes.isEmpty()) return;
        for (FeederGroupTreeNode node : nodes) {
            if (node.getType() == 4) {
                collector.add(node.getName());
            } else if (node.getChildren() != null && !node.getChildren().isEmpty()) {
                collectNodesByType(node.getChildren(), collector);
            }
        }
    }
}
