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

import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import com.hdkj.lt.base.constants.DictConstants;
import com.hdkj.lt.bf.entity.dto.CustomerAccountDTO;
import com.hdkj.lt.bf.entity.vo.BreakerAreaVO;
import com.hdkj.lt.bf.entity.vo.PlanConfirmStateVO;
import com.hdkj.lt.bf.entity.vo.SwitchByUserVO;
import com.hdkj.lt.bf.mapper.*;
import com.hdkj.lt.bf.service.FhzgFaultGenerateGraphService;
import com.hdkj.lt.core.bizms.modle.dto.EventQueryDTO;
import com.hdkj.lt.core.bizms.modle.dto.FhzgFaultTransferSchemePathDetailDTO;
import com.hdkj.lt.core.bizms.modle.dto.FhzgPlanTransferSchemePathDetailDTO;
import com.hdkj.lt.core.bizms.modle.dto.SchemeQueryDTO;
import com.hdkj.lt.core.bizms.modle.po.FeederTopo;
import com.hdkj.lt.core.bizms.modle.po.fault.FaultAwaitTransferSwitchSection;
import com.hdkj.lt.core.bizms.modle.po.fault.FaultPowerCut;
import com.hdkj.lt.core.bizms.modle.po.fault.FaultPowerCutSwitch;
import com.hdkj.lt.core.bizms.modle.po.fault.FaultTransferScheme;
import com.hdkj.lt.core.sys.dao.FhzgOrganSuffixMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
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.util.*;
import java.util.stream.Collectors;

/**
 * 成图服务
 *
 * @author zhuzhe
 * @since 2025-05-22
 */

@Service
public class FhzgFaultGenerateGraphServiceImpl implements FhzgFaultGenerateGraphService {

    @Autowired
    FhzgFaultGenerateGraphMapper fhzgFaultGenerateGraphMapper;

    @Autowired
    FhzgGenerateGraphMapper dfhzgGenerateGraphMapper;

    @Autowired
    FaultTransferSchemePathDetailMapper faultTransferSchemePathDetailMapper;

    @Autowired
    FeederBaseMapper feederBaseMapper;

    @Autowired
    FaultPowerCutSwitchMapper faultPowerCutSwitchMapper;

    @Autowired
    FhzgOrganSuffixMapper fhzgOrganSuffixMapper;

    /**
     * 根据停电范围查询开关列表
     *
     * @param dto
     * @return
     */
    @Override
    public List<BreakerAreaVO> getSwitchListByOutArea(EventQueryDTO dto) {
        List<BreakerAreaVO> result = new ArrayList<>();
        FaultPowerCut fhzgPlanPowerCut = fhzgFaultGenerateGraphMapper.selectFhzgPlanById(dto.getPlanId());
        // 查询故障，获取线路名称
        String lineId = fhzgPlanPowerCut.getLineId();

        // 根据故障id查询停电范围
        List<FaultPowerCutSwitch> cutSwitchList = fhzgFaultGenerateGraphMapper.selectPowerCutSwitchList(dto.getPlanId());
        if (cutSwitchList == null || cutSwitchList.size() == 0) {
            return null;
        }
        String isFullLine = cutSwitchList.get(0).getIsFullLine();
        // 整线停电，返回出线开关
        if ("1".equals(isFullLine)) {
            // 查询出线开关
            LambdaQueryWrapper<FeederTopo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StringUtils.isNotEmpty(lineId), FeederTopo::getFeeder, lineId)
                    .eq(FeederTopo::getIsStartKg, 1)
                    .in(FeederTopo::getPsrType, Arrays.asList(DictConstants.KG_PSR_TYPE.split(",")));
            //动态切换表名
            //*ztj ArgTableNameHandler.setArgument(fhzgOrganSuffixMapper.getOrganSuffixByFaultIdOrLineId(dto.getPlanId(), null));
            List<FeederTopo> leadoutBreakerList = dfhzgGenerateGraphMapper.getFeederTopo(wrapper);
            if (leadoutBreakerList == null || leadoutBreakerList.size() == 0) {
                return null;
            }
            BreakerAreaVO breakerAreaVO = new BreakerAreaVO();
            breakerAreaVO.setStartSwitch(leadoutBreakerList.get(0).getPsrId());
            breakerAreaVO.setIsFullLine("1");
            result.add(breakerAreaVO);
            return result;
        } else {
            // 根据计划id查询转供路径明细  fhzg_fault_transfer_scheme_path_detail  FaultTransferSchemePathDetail
//            List<FaultTransferSchemePathDetail> pathDetailList = fhzgFaultGenerateGraphMapper.selectSchemePathDetailByFault(dto.getPlanId());
            LambdaQueryWrapper<FaultPowerCutSwitch> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(FaultPowerCutSwitch::getFaultId, dto.getPlanId());
            List<FaultPowerCutSwitch> faultPowerCutSwitches = faultPowerCutSwitchMapper.selectList(wrapper);

            if (!CollectionUtils.sizeIsEmpty(faultPowerCutSwitches) && StringUtils.isNotEmpty(faultPowerCutSwitches.get(0).getEndSwitch())) {
                BreakerAreaVO breakerAreaVO = new BreakerAreaVO();
                // 结束开关
//                List<String> endswitchs = pathDetailList.stream().map(FaultTransferSchemePathDetail::getStartSwitchId).collect(Collectors.toList());
                List<String> endswitchs = Arrays.asList(faultPowerCutSwitches.get(0).getEndSwitch().split(","));
                breakerAreaVO.setEndSwitch(endswitchs);
                // 开始开关
                String startStr = cutSwitchList.get(0).getStartSwitch();

                //如果开始开关等于结束开关，就没有中间开关，也没有开始开关，就只有结束开关
                if (!(endswitchs.size() == 1 && endswitchs.contains(startStr))) {
                    breakerAreaVO.setStartSwitch(startStr);
                    //中间开关
                    //动态切换表名
                    //*ztj ArgTableNameHandler.setArgument(fhzgOrganSuffixMapper.getOrganSuffixByFaultIdOrLineId(dto.getPlanId(), null));
                    List<FhzgPlanTransferSchemePathDetailDTO> midSwitchList = fhzgFaultGenerateGraphMapper.getSwitchSectionInfo(lineId, startStr, endswitchs, Arrays.asList(DictConstants.KG_PSR_TYPE.split(",")));
//                    List<String> kgPsrTypes = Arrays.asList(DictConstants.KG_PSR_TYPE.split(","));
//                    List<String> midSwitchList = dfhzgGenerateGraphMapper.getBreakerPsrId(startStr, lineId, DictConstants.OUTAGE_TYPE_ZXS, kgPsrTypes);
                    if (midSwitchList != null && !midSwitchList.isEmpty()) {
                        List<String> midList = midSwitchList.stream().map(FhzgPlanTransferSchemePathDetailDTO::getSwitchId).collect(Collectors.toList());
                        breakerAreaVO.setMidSwitch(midList);
                    }
                }
                breakerAreaVO.setIsFullLine("0");
                result.add(breakerAreaVO);
            } else {
                // 通过线路和 开始开关 查询topo树形结构
                String startStr = cutSwitchList.get(0).getStartSwitch();
                //动态切换表名
                //*ztj ArgTableNameHandler.setArgument(fhzgOrganSuffixMapper.getOrganSuffixByFaultIdOrLineId(dto.getPlanId(), null));
//                List<BrakerTransformerRelationDTO> switchTree = dfhzgGenerateGraphMapper.getBreakerTree(null,
//                        startStr, lineId, Arrays.asList(DictConstants.KG_PSR_TYPE.split(",")));
//                List<String> midList = switchTree.stream().map(BrakerTransformerRelationDTO::getChildPsrId).collect(Collectors.toList());
//                midList.remove(startStr);
                // 注：这里没有结束开关，所以随便传不存在的字符串就行
                List<String> kgPsrTypes = Arrays.asList(DictConstants.KG_PSR_TYPE.split(","));
                List<String> psrList = dfhzgGenerateGraphMapper.getBreakerPsrId(startStr, lineId, DictConstants.OUTAGE_TYPE_ZXS, kgPsrTypes);
                BreakerAreaVO breakerAreaVO = new BreakerAreaVO();
                breakerAreaVO.setMidSwitch(psrList);
                breakerAreaVO.setStartSwitch(startStr);
                result.add(breakerAreaVO);
                return result;
            }
        }
        return result;
    }

    /**
     * 根据停电范围查询开关段列表
     *
     * @param dto
     * @return
     */
    @Override
    public List<BreakerAreaVO> getSwitchListByTransferSection(EventQueryDTO dto) {
        List<BreakerAreaVO> result = new ArrayList<>();
        // 查询停电计划，获取线路名称
        //GridPdOutageEventBase gridPdOutageEventBase = fhzgFaultGenerateGraphMapper.getFaultInfoById(dto.getPlanId());
        FaultPowerCut fhzgPlanPowerCut = fhzgFaultGenerateGraphMapper.selectFhzgPlanById(dto.getPlanId());
        // 查询故障，获取线路名称
        String lineId = fhzgPlanPowerCut.getLineId();
        // 根据故障id查询故障开关段
        List<FaultAwaitTransferSwitchSection> cutSwitchList = fhzgFaultGenerateGraphMapper.selectSwitchSectionList(dto.getPlanId());
        if (cutSwitchList == null || cutSwitchList.size() == 0) {
            return null;
        }
        //*ztj String organSuffix = fhzgOrganSuffixMapper.getOrganSuffixByFaultIdOrLineId(null, lineId);
        // 动态切换表名
        //*ztj ArgTableNameHandler.setArgument(organSuffix);
        List<Map<String, String>> psrList = dfhzgGenerateGraphMapper.getBreakerPsrIdByFaultId(dto.getPlanId());
        if (ObjectUtils.isNotEmpty(psrList)) {
            String startSwitchId = psrList.get(0).get("start_switch_id");
            List<String> endSwitchIds = psrList.stream().map(e -> e.get("end_switch_id")).collect(Collectors.toList());
            List<String> midSwitchIds = Lists.newArrayList();
            cutSwitchList.forEach(e -> {
                if (StringUtils.isNotBlank(e.getEndSwitchId())) {
                    // 添加分段开关尾开关到中间开关
                    midSwitchIds.addAll(Arrays.asList(e.getEndSwitchId().split(",")).stream()
                            .filter(en -> !endSwitchIds.contains(en)).collect(Collectors.toList()));
                }
                // 添加分段开关尾开始开关到中间开关
                if (!StringUtils.equals(e.getStartSwitchId(), startSwitchId)) {
                    midSwitchIds.add(e.getStartSwitchId());
                }
            });
            // 动态切换表名
            //*ztj ArgTableNameHandler.setArgument(organSuffix);
            // 获取中间的母线信息
            List<String> psrIdList = dfhzgGenerateGraphMapper.getBusbarBySwitchIds(ListUtils.union(midSwitchIds, Arrays.asList(startSwitchId)));
            BreakerAreaVO breakerAreaVO = new BreakerAreaVO();
            breakerAreaVO.setStartSwitch(startSwitchId).setEndSwitch(endSwitchIds).setMidSwitch(ListUtils.union(midSwitchIds, psrIdList));
            result.add(breakerAreaVO);
        }
        /*for (FaultAwaitTransferSwitchSection transferSwitchSection : cutSwitchList) {
            String startStr = transferSwitchSection.getStartSwitchId();
            String endStr = transferSwitchSection.getEndSwitchId();
            BreakerAreaVO breakerAreaVO = new BreakerAreaVO();
            // 结束开关为空，返回开始开关
            breakerAreaVO.setStartSwitch(startStr);
            if (endStr != null) {
                List<String> endSwitchs = Arrays.asList(endStr.split(","));
                breakerAreaVO.setEndSwitch(endSwitchs);
            }
            ArgTableNameHandler.setArgument(fhzgOrganSuffixMapper.getOrganSuffixByFaultIdOrLineId(null, lineId));
            List<String> psrList = dfhzgGenerateGraphMapper.getBreakerPsrId(startStr, lineId, endStr);
            breakerAreaVO.setMidSwitch(psrList);
            result.add(breakerAreaVO);
        }*/
        return result;
    }

    /**
     * @param dto
     * @return
     */
    @Override
    public SwitchByUserVO getSwitchByCustomer(CustomerAccountDTO dto) {
//        SwitchByUserVO result = new SwitchByUserVO();
//        // 查询用户信息
//        FhzgDistCustomer fhzgDistCustomer = dfhzgGenerateGraphMapper.selectCustomerById(dto.getCustomerId());
//        //所属变压器编码
//        String transformerNo = fhzgDistCustomer.getTransformerNo();
//
//        //用户查询所属开关，根据 transformerNo 从topo表中查询上一级开关
//        List<SwitchByUserVO> topoList = dfhzgGenerateGraphMapper.selectSwitchByCustomer(transformerNo, Arrays.asList(DictConstants.KG_PSR_TYPE.split(",")));
//        if (topoList !=null && topoList.size() > 0 ) {
//            result = topoList.get(0);
//        }
//
//        result.setIsCriticalUser(fhzgDistCustomer.getIsCriticalUser());
//        return result;
        //动态切换表名
        //*ztj ArgTableNameHandler.setArgument(fhzgOrganSuffixMapper.getOrganSuffixFaultByCustomerId(dto.getCustomerId()));
        String switchId = fhzgFaultGenerateGraphMapper.selectSwitchByCustomerId(dto.getCustomerId());
        SwitchByUserVO result = new SwitchByUserVO();
        result.setPsrId(switchId);
        return result;
    }

    @Override
    public List<BreakerAreaVO> getPathOverviewSwitch(SchemeQueryDTO dto) {
        List<BreakerAreaVO> result = new ArrayList<>();
        FaultTransferScheme fhzgPlanTransferScheme = new FaultTransferScheme();
        fhzgPlanTransferScheme.setId(dto.getSchemeId());

        // 根据方案id 查询转供路径
        List<FhzgFaultTransferSchemePathDetailDTO> pathDetailList =
                faultTransferSchemePathDetailMapper.getTransferSchemePathDetailByCombinationSchemeId(fhzgPlanTransferScheme);
        if (pathDetailList == null || pathDetailList.size() == 0) {
            return null;
        }
        // 对侧线路的主线开关ID结果
        Map<String, List<String>> lineSwitchMap = MapUtil.newHashMap();
        // 对侧线路ID集合，用于查询对侧线路的主线开关ID
        List<String> lindIds = pathDetailList.stream().map(FhzgFaultTransferSchemePathDetailDTO::getOppositeLineId).collect(Collectors.toList());
        if (ObjectUtils.isNotEmpty(lindIds)) {
            // 查询对侧线路的主线开关信息
            List<String> kgPsrTypes = Arrays.asList(DictConstants.KG_PSR_TYPE.split(","));
            //动态切换表名
            //*ztj ArgTableNameHandler.setArgument(fhzgOrganSuffixMapper.getOrganSuffixByFaultIdOrLineId(dto.getPlanId(), null));
            List<FeederTopo> feederSwitchList = feederBaseMapper.getFeederSwitchListById(lindIds, kgPsrTypes);
            // 根据线路分组，取对侧线路的开关ID集合
            lineSwitchMap.putAll(feederSwitchList.stream().collect(Collectors.groupingBy(
                    FeederTopo::getFeeder,
                    Collectors.mapping(FeederTopo::getPsrId, Collectors.toList()))));
        }
        //动态切换表名
        //*ztj ArgTableNameHandler.setArgument(fhzgOrganSuffixMapper.getOrganSuffixFaultBySchemeId(dto.getSchemeId()));
        // 20250706 添加查询本侧线路转供路径的母线信息
        List<String> kgPsrTypes = Arrays.asList(DictConstants.KG_PSR_TYPE.split(","));
        Map<String, List<String>> oppositeSwitchMap = faultTransferSchemePathDetailMapper.getFeederBusbarBySchemeId(dto.getSchemeId(), kgPsrTypes)
                .stream().collect(Collectors.groupingBy(e -> e.getString("xl_id"), Collectors.mapping(e -> e.getString("psr_id"), Collectors.toList())));
        // 方案的所有开始开关
        List<String> startList = Arrays.stream(pathDetailList.stream().map(e -> e.getStartSwitchId())
                .collect(Collectors.joining(",")).split(",")).distinct().collect(Collectors.toList());

        for (FhzgFaultTransferSchemePathDetailDTO pathDetail : pathDetailList) {
            String startId = pathDetail.getStartSwitchId();
            String midIds = pathDetail.getSwitchSectionId();
            String endIds = pathDetail.getEndSwitchId();

            BreakerAreaVO breakerAreaVO = new BreakerAreaVO();
            breakerAreaVO.setOppositeLineId(pathDetail.getOppositeLineId());
            breakerAreaVO.setStartSwitch(startId);
            if (midIds != null) {
                // 方案对应的本侧线路的母线信息
                List<String> midDeviceIdList = Optional.ofNullable(oppositeSwitchMap.get(pathDetail.getOppositeLineId())).orElse(Lists.newArrayList());
                // 对侧线路对应的开关和母线信息
                List<String> oppositeSwitch = Optional.ofNullable(lineSwitchMap.get(pathDetail.getOppositeLineId())).orElse(Lists.newArrayList());
                // 添加中间设备本侧母线+对侧线路开关母线ID
                midDeviceIdList.addAll(oppositeSwitch);
                // 当对侧线路的结束开关 和 其他转供线路的开始开关一致时，需要添加此开关到中间开关中
                if (ObjectUtils.allNotNull(startList, endIds)) {
                    List<String> appendKgList = Arrays.stream(endIds.split(",")).filter(e -> startList.contains(e)).collect(Collectors.toList());
                    midDeviceIdList.addAll(appendKgList);
                }
                breakerAreaVO.setMidSwitch(ListUtils.union(Arrays.asList(midIds.split(",")), midDeviceIdList));
            }
            if (endIds != null) {
                breakerAreaVO.setEndSwitch(Arrays.asList(endIds.split(",")));
            }
            result.add(breakerAreaVO);
        }

        return result;
    }

    @Override
    public SwitchByUserVO getSwitchByDevice(CustomerAccountDTO dto) {
        SwitchByUserVO result = new SwitchByUserVO();
        LambdaQueryWrapper<FeederTopo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FeederTopo::getPsrId, dto.getTransformerNo());
        //此处涉及接口未使用，未调用动态切换表名方法
        List<FeederTopo> leadoutBreakerList = dfhzgGenerateGraphMapper.getFeederTopo(wrapper);
        if (leadoutBreakerList != null && leadoutBreakerList.size() > 0) {
            result.setPsrId(leadoutBreakerList.get(0).getStartKgId());
        }
        return result;
    }


    @Override
    public PlanConfirmStateVO getPlanConfirmState(SchemeQueryDTO dto) {
        PlanConfirmStateVO result = new PlanConfirmStateVO();
        FaultPowerCut powerCut = fhzgFaultGenerateGraphMapper.selectFhzgPlanById(dto.getPlanId());
        result.setSchemeState(powerCut.getSchemeState());
        return result;
    }
}
