package com.hdkj.lt.mq.service.fault.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.lang.generator.SnowflakeGenerator;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hdkj.lt.base.constants.DictConstants;
import com.hdkj.lt.core.bizms.modle.po.FhzgSwitchProtectionSettings;
import com.hdkj.lt.core.bizms.modle.po.fault.*;
import com.hdkj.lt.core.bizms.mp.ArgTableNameHandler;
import com.hdkj.lt.core.sys.dao.FhzgOrganSuffixMapper;
import com.hdkj.lt.core.sys.service.SwitchProtectionSettingsService;
import com.hdkj.lt.modle.dto.jsty.*;
import com.hdkj.lt.mq.entity.po.FhzgFaultPowerCut;
import com.hdkj.lt.mq.mapper.fault.FhzgFaultAnalyzeCalculateDecudeMapper;
import com.hdkj.lt.mq.service.fault.FhzgFaultAnalyzeCalculateDecudeService;
import com.hdkj.lt.mq.service.fault.IFaultTransferSchemeSwitchingFinalSegCurrentDetailService;
import com.hdkj.lt.mq.service.fault.IFaultTransferSchemeSwitchingFinalSwCurrentDetailService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * 停电转供方案信息表 服务实现类
 *
 * @author zhuzhe
 * @since 2025-05-23
 */
@Service
@Slf4j
public class FhzgFaultAnalyzeCalculateDecudeServiceImpl implements FhzgFaultAnalyzeCalculateDecudeService {

    @Autowired
    FhzgFaultAnalyzeCalculateDecudeMapper fhzgFaultAnalyzeCalculateDecudeMapper;

    @Autowired
    FhzgOrganSuffixMapper fhzgOrganSuffixMapper;
    @Autowired
    IFaultTransferSchemeSwitchingFinalSegCurrentDetailService faultTransferSchemeSwitchingFinalSegCurrentDetailService;
    @Autowired
    IFaultTransferSchemeSwitchingFinalSwCurrentDetailService faultTransferSchemeSwitchingFinalSwCurrentDetailService;
    @Autowired
    SwitchProtectionSettingsService fhzgSwitchProtectionSettingsService;

    @Override
    public void analyzeCalculateDecudeData(Long faultId, List<SupplyAreaDTO> supplyAreaList) {
        // 根据计划id 删除 用户 和 开关段信息
        fhzgFaultAnalyzeCalculateDecudeMapper.deleteTransferUserByFaultId(faultId);
        fhzgFaultAnalyzeCalculateDecudeMapper.deleteSwitchSectionByFaultId(faultId);
        //根据计划id 查询线路名
        FhzgFaultPowerCut fhzgFaultPowerCut = fhzgFaultAnalyzeCalculateDecudeMapper.getLineNameByFaultId(faultId);
        String lineId = fhzgFaultPowerCut.getLineId();
        for (int i = 0; i < supplyAreaList.size(); i++) {
            SupplyAreaDTO supplyAreaDTO = supplyAreaList.get(i);
            // 带转供开关段--开始开关
            BreakerInfoDTO isolateBreaker = supplyAreaDTO.getIsolateBreaker();

            // 线路和首开关id
            String breakerPSRID = isolateBreaker.getBreakerPSRID();

            // 根据线路和首开关 查询开关段并保存  todo  现在场景只有首开关，后面的场景有终止开关，数据结构未定
            //动态切换表名
            //*ztj ArgTableNameHandler.setArgument(fhzgOrganSuffixMapper.getOrganSuffixByFaultIdOrLineId(faultId, null));
            List<FaultAwaitTransferSwitchSection> switchSectionList = fhzgFaultAnalyzeCalculateDecudeMapper.getSwitchSection(lineId, breakerPSRID, Arrays.asList(DictConstants.KG_PSR_TYPE.split(",")));

            if (switchSectionList != null && switchSectionList.size() > 0) {
                switchSectionList.stream().forEach(e -> e.setFaultId(faultId).setAreaPsrId(breakerPSRID).setSwitchName(e.getStartSwitchName()));
                fhzgFaultAnalyzeCalculateDecudeMapper.saveSwitchSectionBatch(switchSectionList);
            }
        }

        // 更新开关段负荷
        // fhzgFaultAnalyzeCalculateDecudeMapper.updateSwitchSectionSwitchLoads();
    }

    /**
     * 合环校验
     *
     * @param faultId
     * @param xferFaultMap
     */
    @Override
    public void analyzeXferFaultList(Long faultId, Map<Long, XferPlanDTO> xferFaultMap, LoopCheckRuleDTO loopCheckRuledto, Map<String, FeederCheckRuleDTO> feederCheckRuleDTOMap) {
        // 查询本侧线路
        FhzgFaultPowerCut fhzgFaultPowerCut = fhzgFaultAnalyzeCalculateDecudeMapper.getLineNameByFaultId(faultId);
        Snowflake snowflake = IdUtil.getSnowflake(1, 1);
        for (Long schemeId : xferFaultMap.keySet()) {
            // 根据方案ID获取方案数据
            XferPlanDTO xferFaultDTO = xferFaultMap.get(schemeId);
            // 获取开关动作列表
            List<BreakerInfoDTO> breakerOperationOrderList = xferFaultDTO.getBreakerOperationOrderListList().get(0);
            // 合环校验的参数配置
            LoopCheckRuleDTO loopCheckRule = Optional.ofNullable(loopCheckRuledto).orElse(new LoopCheckRuleDTO());

            //转供方案开关及设备区域信息
            List<XferSupplyAreaDTO> xferSupplyAreaList = xferFaultDTO.getXferSupplyAreaList();
            Map<String, XferSupplyAreaDTO> mapSupplyArea = xferSupplyAreaList.stream()
                    .filter(k -> ObjectUtils.isNotEmpty(k.getLinkSwitch()))
                    .collect(Collectors.toMap(k -> k.getLinkSwitch().getPsrID(), v -> v));
            int seq = 0;
            boolean orderIdIsAllNull = breakerOperationOrderList.stream().allMatch(i -> i.getOrderId() == null);
            breakerOperationOrderList.sort(Comparator.comparing(BreakerInfoDTO::getBreakerOperation));
            for (BreakerInfoDTO breakerInfoDTO : breakerOperationOrderList) {
                FaultTransferSchemeSwitchingSequence switchingSequence = new FaultTransferSchemeSwitchingSequence();
                Long switchingSequenceId = snowflake.nextId();
                switchingSequence.setId(switchingSequenceId);
                switchingSequence.setSchemeId(schemeId);
                switchingSequence.setSwitchId(breakerInfoDTO.getBreakerPSRID());
                switchingSequence.setSwitchName(breakerInfoDTO.getBreakerName());
                switchingSequence.setSwitchType("0");
                // 是 三遥 开关
                if (StringUtils.isNotEmpty(breakerInfoDTO.getAutoType()) && breakerInfoDTO.getAutoType().equals("auto3Y")) {
                    switchingSequence.setIsAutoSwitch("1");
                } else {
                    switchingSequence.setIsAutoSwitch("0");
                }
                switchingSequence.setOperationContent(String.valueOf(breakerInfoDTO.getBreakerOperation()));
                //操作顺序
                if (orderIdIsAllNull) {
                    switchingSequence.setSwitchingSeq(seq++);
                } else {
                    switchingSequence.setSwitchingSeq(breakerInfoDTO.getOrderId());
                }
                //switchingSequence.setLoopCloseCheck();

                // 合环校验和终态校验
                XferSupplyAreaDTO xferSupplyAreaDTO = mapSupplyArea.get(breakerInfoDTO.getBreakerPSRID());

                if (xferSupplyAreaDTO != null) {
                    LinkLineDTO linkLineInfo = Optional.ofNullable(xferSupplyAreaDTO.getLinkLineInfo()).orElse(new LinkLineDTO());
                    // 合环校验 故障停电没有合环校验
                    FinalCheckDTO finalCheck = Optional.ofNullable(xferSupplyAreaDTO.getFinalCheck()).orElse(new FinalCheckDTO());
                    //终态校验
                    FaultTransferSchemeSwitchingFinalCheck switchingFinalCheck = new FaultTransferSchemeSwitchingFinalCheck();
                    switchingFinalCheck.setId(snowflake.nextId());
                    switchingFinalCheck.setSwitchingId(switchingSequenceId);
                    // 本侧线路
                    switchingFinalCheck.setLineId(fhzgFaultPowerCut.getLineId());
                    switchingFinalCheck.setLineName(fhzgFaultPowerCut.getLineName());
                    // 对侧线路
                    switchingFinalCheck.setOppositeLineId(linkLineInfo.getPsrID());
                    switchingFinalCheck.setOppositeLineName(linkLineInfo.getName());

                    FeederCheckRuleDTO feederCheckRuleDTO = feederCheckRuleDTOMap.get(linkLineInfo.getPsrID());
                    //对侧线路 额定电流
                    if (feederCheckRuleDTO != null) {
                        switchingFinalCheck.setAllowMaxCurrent(String.valueOf(feederCheckRuleDTO.getRateCurrent()));
                    }
                    // 对侧预估最大电流
                    switchingFinalCheck.setEstimateMaxCurrent(linkLineInfo.getPlanMaxCurrentValue() == null ? "" : linkLineInfo.getPlanMaxCurrentValue().toString());

                    // 对侧预估最大负载率
                    switchingFinalCheck.setEstimateMaxLoadFactor(linkLineInfo.getPlanMaxCurrentLoad() == null ? "" : linkLineInfo.getPlanMaxCurrentLoad().toString());
                    //负载率判断值
                    Double feederLoadRate = new Double(100);
                    switchingFinalCheck.setLoadFactorThreshold(feederLoadRate.toString());
//                    Double feederLoadRate = loopCheckRule.getFeederLoadRate();
//                    if (feederLoadRate != null) {
//                        switchingFinalCheck.setLoadFactorThreshold(feederLoadRate.toString());
//                    } else {
//                        //推演平台如果没有返回值固定写上100
//                        feederLoadRate = new Double(100);
//                        switchingFinalCheck.setLoadFactorThreshold(feederLoadRate.toString());
//                    }
                    //负载率校验结果  对侧预计负载率<负载率判定值即为通过
                    Double planMaxCurrentLoad = linkLineInfo.getPlanMaxCurrentLoad();
                    if (feederLoadRate != null && planMaxCurrentLoad != null) {
                        switchingFinalCheck.setLoadFactorCheck(feederLoadRate.compareTo(planMaxCurrentLoad) > 0 ? "1" : "0");
                    } else {
                        switchingFinalCheck.setLoadFactorCheck("0");
                    }
                    // 对侧预估最大负载率
//                    if (linkLineInfo.getRateCurrent() != null && linkLineInfo.getPlanMaxCurrentValue() != null) {
//                        BigDecimal fac = BigDecimal.valueOf(linkLineInfo.getPlanMaxCurrentValue())
//                                .multiply(BigDecimal.valueOf(100.0))
//                                .divide(BigDecimal.valueOf(linkLineInfo.getRateCurrent()),2, RoundingMode.HALF_UP);
//                        if (fac.compareTo(new BigDecimal(100)) < 0) {
//                            switchingFinalCheck.setLoadFactorCheck("1");
//                            switchingSequence.setFinalStateCheck("1");
//                        } else {
//                            switchingFinalCheck.setLoadFactorCheck("0");
//                            switchingSequence.setFinalStateCheck("0");
//                        }
//                        String maxLoadFactor = String.format("%s%%",fac);
//                        switchingFinalCheck.setEstimateMaxLoadFactor(maxLoadFactor);
//                    } else {
//                        switchingFinalCheck.setLoadFactorCheck("0");
//                        switchingSequence.setFinalStateCheck("0");
//                    }
                    //保存终态校验导线电流明细
                    List<FinalSegResultDTO> finalSegResultDTOList = finalCheck.getSegResult();
                    if (CollUtil.isNotEmpty(finalSegResultDTOList)) {
                        saveFinalSegCurrentDetail(switchingSequenceId, finalSegResultDTOList);
                        switchingFinalCheck.setSegmentCurrentCheck("0");//只要有数据就是校验不通过
                    } else {
                        switchingFinalCheck.setSegmentCurrentCheck("1");//没有校验失败的数据
                    }
                    //保存终态校验 开关电流明细
                    List<FinalBreakerSafetyCheckResultDTO> finalBreakerSafetyCheckResultDTO = finalCheck.getBreakerSafetyCheckResult();
                    if (CollUtil.isNotEmpty(finalBreakerSafetyCheckResultDTO)) {
                        //在校验不通过的开关列表中筛选出终态校验不通过的数据checkType ='2' 或者"3"
                        List<FinalBreakerSafetyCheckResultDTO> finalBreakerSafetyCheckResultFinalDTO = finalBreakerSafetyCheckResultDTO.stream().filter(e -> StrUtil.equals(e.getCheckType(), "2") || StrUtil.equals(e.getCheckType(), "3")).collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(finalBreakerSafetyCheckResultFinalDTO)) {
                            //只要有数据则说明开关 电流校验不通过
                            switchingFinalCheck.setSwitchCurrentCheck("0");
                            saveFinalSwCurrentDetail(switchingSequenceId, finalBreakerSafetyCheckResultFinalDTO);
                        } else {
                            switchingFinalCheck.setSwitchCurrentCheck("1");
                        }
                    } else {
                        switchingFinalCheck.setSwitchCurrentCheck("1");//没有校验失败的数据
                    }
                    // 设置终态校验结果  对侧最大负载率校验结果，加终态校验开关校验结果，开关电流导线校验结果
                    String loadFactorCheck = switchingFinalCheck.getLoadFactorCheck();
                    String switchCurrentCheck = switchingFinalCheck.getSwitchCurrentCheck();
                    String segmentCurrentCheck = switchingFinalCheck.getSegmentCurrentCheck();
                    switchingSequence.setFinalStateCheck("1");//设置终态校验默认为通过
                    // 只要有对侧最大负载率校验结果或者开关校验结果不通过，或导线校验不通过则开关动作顺序校验结果为不通过
                    if (StrUtil.equals(loadFactorCheck, "0") || StrUtil.equals(switchCurrentCheck, "0") || StrUtil.equals(segmentCurrentCheck, "0")) {
                        switchingSequence.setFinalStateCheck("0");
                    }
                    // 负载率 判定值 目前没有，校验结果均为通过
//                    switchingFinalCheck.setLoadFactorThreshold("1");
                    fhzgFaultAnalyzeCalculateDecudeMapper.saveSwitchingFinalCheck(switchingFinalCheck);
                }
                // 保存开关顺序
                fhzgFaultAnalyzeCalculateDecudeMapper.saveSwitchingSequence(switchingSequence);
            }
        }
    }

    //保存终态 开关电流校验
    private void saveFinalSwCurrentDetail(Long switchingId, List<FinalBreakerSafetyCheckResultDTO> finalBreakerSafetyCheckResultList) {
        //查询开关的设置信息
        List<String> psrIdList = finalBreakerSafetyCheckResultList.stream().filter(e -> StrUtil.isNotBlank(e.getBreakerPSRID())).map(FinalBreakerSafetyCheckResultDTO::getBreakerPSRID).collect(Collectors.toList());
        List<FhzgSwitchProtectionSettings> switchProtectionSettingsList = fhzgSwitchProtectionSettingsService.list(new LambdaQueryWrapper<FhzgSwitchProtectionSettings>().in(FhzgSwitchProtectionSettings::getDevicePrsId, psrIdList));
        Map<String, String> stringFhzgSwitchProtectionSettingsMap = switchProtectionSettingsList.stream().collect(Collectors.toMap(FhzgSwitchProtectionSettings::getDevicePrsId, FhzgSwitchProtectionSettings::getOc3Value, (k1, k2) -> k2));
        List<FaultTransferSchemeSwitchingFinalSwCurrentDetail> list = new ArrayList<>();
        finalBreakerSafetyCheckResultList.forEach(e -> {
            String currentThreshold = stringFhzgSwitchProtectionSettingsMap.get(e.getBreakerPSRID());
            FaultTransferSchemeSwitchingFinalSwCurrentDetail faultTransferSchemeSwitchingFinalSwCurrentDetail = new FaultTransferSchemeSwitchingFinalSwCurrentDetail();
            faultTransferSchemeSwitchingFinalSwCurrentDetail.setSwitchingId(switchingId)
                    .setSwitchId(e.getBreakerPSRID())
                    .setSwitchName(e.getName())
                    .setLineName(e.getFeederName())
                    .setSwitchCurrentCheck("0")//列表中取出的数据都是校验不通过的数据
                    .setMaxAfter24hI(e.getMaxAfter24hI() == null ? null : e.getMaxAfter24hI().toString())
                    .setCurrentThreshold(currentThreshold)//判定值
                    .setCreateTime(LocalDateTime.now());
            list.add(faultTransferSchemeSwitchingFinalSwCurrentDetail);
        });
        faultTransferSchemeSwitchingFinalSwCurrentDetailService.saveBatch(list);
    }

    //保存终态 导线电流校验
    private void saveFinalSegCurrentDetail(Long switchingId, List<FinalSegResultDTO> finalSegResultDTOList) {
        List<FaultTransferSchemeSwitchingFinalSegCurrentDetail> list = new ArrayList<>();
        finalSegResultDTOList.forEach(e -> {
            FaultTransferSchemeSwitchingFinalSegCurrentDetail faultTransferSchemeSwitchingFinalSegCurrentDetail = new FaultTransferSchemeSwitchingFinalSegCurrentDetail();
            faultTransferSchemeSwitchingFinalSegCurrentDetail.setSwitchingId(switchingId)
                    .setSegmentId(e.getSegmentPSRID())
                    .setSegmentName(e.getName())
                    .setLineName(e.getFeederName())
                    .setSegmentCurrentCheck("0")//列表中取出的数据都是校验不通过的数据
                    .setMaxAfter24hI(e.getMaxAfterI() == null ? null : e.getMaxAfterI().toString())
                    .setRatedI(e.getRatedI() == null ? null : e.getRatedI().toString())
                    .setCreateTime(LocalDateTime.now());
            list.add(faultTransferSchemeSwitchingFinalSegCurrentDetail);
        });
        faultTransferSchemeSwitchingFinalSegCurrentDetailService.saveBatch(list);
    }

}
