package com.hdkj.lt.bf.application;

import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hdkj.fhzg.optimization.response.FeederGroupTreeNode;
import com.hdkj.lt.base.constants.DictConstants;
import com.hdkj.lt.bf.constants.OptimizationConstants;
import com.hdkj.lt.bf.entity.TJxz;
import com.hdkj.lt.bf.entity.TJxzXl;
import com.hdkj.lt.bf.entity.convert.EntityToVOConvertor;
import com.hdkj.lt.bf.entity.vo.BreakerAreaVO;
import com.hdkj.lt.bf.entity.vo.FeederDeviceVO;
import com.hdkj.lt.bf.entity.vo.XlRelVO;
import com.hdkj.lt.bf.mapper.FhzgGridOperationAbnormalityMapper;
import com.hdkj.lt.bf.mapper.TJxzXlMapper;
import com.hdkj.lt.bf.service.TJxzService;
import com.hdkj.lt.bf.service.TJxzXlService;
import com.hdkj.lt.bf.service.impl.XlRelServiceImpl;
import com.hdkj.lt.core.bizms.modle.po.DwdShbDsFeederBase;
import com.hdkj.lt.core.bizms.modle.po.XlRel;
import com.hdkj.lt.core.sys.dao.FhzgDistMappingFileMapper;
import com.hdkj.lt.core.sys.model.dto.FhzgDistMappingFileDTO;
import com.hdkj.lt.core.sys.service.DwdShbDsFeederBaseService;
import com.hdkj.lt.utils.cache.RedisRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

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

/**
 * @author rj
 * @date 2026/5/22 15:22
 * @description
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class FeederGroupApplication {

    private final TJxzService jxzService;
    private final TJxzXlService jxzXlService;
    private final TJxzXlMapper tJxzXlMapper;
    private final FhzgDistMappingFileMapper distMappingFileMapper;
    private final XlRelServiceImpl xlRelService;
    private final RedisRepository redisRepository;
    private final DwdShbDsFeederBaseService dwdShbDsFeederBaseService;
    private final FhzgGridOperationAbnormalityMapper fhzgGridOperationAbnormalityMapper;


    public List<FeederGroupTreeNode> getFeederGroupTree() {
        Boolean exists = redisRepository.exists(OptimizationConstants.CACHE_KEY_FEEDER_GROUP_TREE);
        if (!exists) {
            //目前仅接入长阳县 洪湖 秭归
            List<String> maintOrgList = Arrays.asList("60FDC66B3FC143DC9C39001215DDCC61", "54C4BBBB8FE4428E96B6AE12247C4DD4", "BA6481B8F34143FDA7E1C35A76846911");
            List<DwdShbDsFeederBase> feederList = dwdShbDsFeederBaseService.lambdaQuery().eq(DwdShbDsFeederBase::getPsrState, "20")
                    .eq(DwdShbDsFeederBase::getPubPrivFlag, "0")
                    .in(DwdShbDsFeederBase::getMaintOrg, maintOrgList).list();
//            List<DwdShbDsFeederBase> feederList = dwdShbDsFeederBaseService.getFeederListByMaintOrg("60FDC66B3FC143DC9C39001215DDCC61");
            List<FeederGroupTreeNode> feederGroupTree = buildFeederGroupTree(feederList);
            redisRepository.setExpire(OptimizationConstants.CACHE_KEY_FEEDER_GROUP_TREE, feederGroupTree,6, TimeUnit.HOURS);
            return feederGroupTree;
        }
        return (List<FeederGroupTreeNode>) redisRepository.get(OptimizationConstants.CACHE_KEY_FEEDER_GROUP_TREE);

    }

    private List<FeederGroupTreeNode> buildFeederGroupTree(List<DwdShbDsFeederBase> rawList) {
        List<TJxz> jxzList = jxzService.list();
        Map<String, Long> jxzFileMap = jxzList.stream().collect(Collectors.toMap(TJxz::getJxzId, TJxz::getFileId));
        List<TJxzXl> jxzxlList = jxzXlService.list();
        Map<String, TJxzXl> jxzXlMap = jxzxlList.stream().collect(Collectors.toMap(TJxzXl::getXlid, i -> i));

        //线路单线图文件id
        List<String> xlIds = jxzxlList.stream().map(TJxzXl::getXlid).collect(Collectors.toList());
        List<FhzgDistMappingFileDTO> mappingFileById = distMappingFileMapper.getMappingFileById(xlIds);
        Map<String, Long> mappingFileMap = mappingFileById.stream().filter(i -> Objects.equals(i.getFileType(), "1")).collect(Collectors.toMap(FhzgDistMappingFileDTO::getLineId, FhzgDistMappingFileDTO::getFileId));

        Map<String, FeederGroupTreeNode> cityMap = rawList.stream().collect(Collectors.toMap(
                DwdShbDsFeederBase::getCity, row -> new FeederGroupTreeNode().setId(row.getCity()).setName(row.getCityName()).setType(1).setChildren(new ArrayList<>()),
                (existing, replacement) -> existing
        ));

        Map<String, FeederGroupTreeNode> maintOrgMap = new HashMap<>();
        Map<String, FeederGroupTreeNode> substationMap = new HashMap<>();


        rawList.forEach(row -> {
            FeederGroupTreeNode cityNode = cityMap.get(row.getCity());
            FeederGroupTreeNode maintOrgNode = maintOrgMap.computeIfAbsent(
                    row.getCity() + "_" + row.getMaintOrg(),
                    k -> {
                        FeederGroupTreeNode newMaintOrgNode = new FeederGroupTreeNode().setId(row.getMaintOrg()).setName(row.getMaintOrgName()).setType(2).setChildren(new ArrayList<>());
                        cityNode.getChildren().add(newMaintOrgNode);
                        return newMaintOrgNode;
                    }
            );

            FeederGroupTreeNode substationNode = substationMap.computeIfAbsent(
                    row.getCity() + "_" + row.getMaintOrg() + "_" + row.getStartStation(),
                    l -> {
                        FeederGroupTreeNode newLabelNode = new FeederGroupTreeNode().setId(row.getStartStation()).setName(row.getStartStationName()).setType(3).setChildren(new ArrayList<>());
                        maintOrgNode.getChildren().add(newLabelNode);
                        return newLabelNode;
                    }
            );

            TJxzXl tJxzXl = jxzXlMap.get(row.getPsrId());
            FeederGroupTreeNode.FileType fileType = new FeederGroupTreeNode.FileType().setFileId(mappingFileMap.get(row.getPsrId())).setFileType("1");

            FeederGroupTreeNode.FileType fileType1 = new FeederGroupTreeNode.FileType().setFileId(tJxzXl == null ? null : tJxzXl.getSwitchSectionFileId()).setFileType("2");
            FeederGroupTreeNode.FileType fileType2 = new FeederGroupTreeNode.FileType().setFileId(tJxzXl == null ? null : tJxzXl.getLoadGroupFileId()).setFileType("3");
            FeederGroupTreeNode.FileType fileType3 = new FeederGroupTreeNode.FileType().setFileId(tJxzXl == null ? null : tJxzXl.getPrimaryFileId()).setFileType("4");
            FeederGroupTreeNode.FileType fileType4 = new FeederGroupTreeNode.FileType().setFileId(jxzFileMap.get(tJxzXl == null ? null : tJxzXl.getJxzId())).setFileType("5");

            List<FeederGroupTreeNode.FileType> fileTypeList = new ArrayList<>();
            fileTypeList.add(fileType);
            fileTypeList.add(fileType1);
            fileTypeList.add(fileType2);
            fileTypeList.add(fileType3);
            fileTypeList.add(fileType4);


            substationNode.getChildren().add(
                    new FeederGroupTreeNode().setId(row.getPsrId()).setName(row.getName()).setType(4)
                            .setFileIdList(fileTypeList));

        });
        return new ArrayList<>(cityMap.values());
    }

    public List<XlRelVO> getFeederGroupContactSwitchList(String feederId) {
        TJxzXl jxzXl = jxzXlService.getOne(new LambdaQueryWrapper<TJxzXl>().eq(TJxzXl::getXlid, feederId));
        List<XlRel> xlRelList = new ArrayList<>();
        if (jxzXl.getJxzId() != null) {
            List<TJxzXl> list = jxzXlService.list(new LambdaQueryWrapper<TJxzXl>().eq(TJxzXl::getJxzId, jxzXl.getJxzId()));
            List<String> xlIds = list.stream().map(TJxzXl::getXlid).collect(Collectors.toList());
            if (!xlIds.isEmpty()) {
                xlRelList = xlRelService.list(new LambdaQueryWrapper<XlRel>().in(XlRel::getXlIdOne, xlIds));
            }
        }
        return EntityToVOConvertor.INSTANCE.toXlRelVOList(xlRelList);
    }

    /**
     * 通过接线组ID查询默认态开关段
     * @param feederId 接线组id
     * @return List
     */
    public List<List<BreakerAreaVO>> getOverviewSwitchByFeederGroupId(String feederId){
        //获取开关类型
        List<String> kgPsrTypes = Arrays.asList(DictConstants.KG_PSR_TYPE.split(","));
        // 根据接线组ID获取线路
        List<TJxzXl> jxzList = tJxzXlMapper.selectJxzXlList(feederId);
        if(CollectionUtils.size(jxzList) > 0){
            List<String> feederIds = jxzList.stream().map(TJxzXl::getXlid).collect(Collectors.toList());
            //根据线路获取所属变电站
            LambdaQueryWrapper<DwdShbDsFeederBase> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(DwdShbDsFeederBase::getPsrId, feederIds);
            List<DwdShbDsFeederBase> list = dwdShbDsFeederBaseService.list(wrapper);
            Map<String, String> stationMap = list.stream().collect(Collectors.toMap(DwdShbDsFeederBase::getPsrId, DwdShbDsFeederBase::getStartStation));
            List<BreakerAreaVO> breakerAreaList = Lists.newArrayList();
            feederIds.forEach(feeder->{
                Map<String, List<String>> feederSwitchMap = MapUtil.newHashMap();
                //*ztj ArgTableNameHandler.setArgument(fhzgOrganSuffixMapper.getOrganSuffixByPsrIdOrFeeder(null, feeder));
                List<FeederDeviceVO> feederDeviceList = fhzgGridOperationAbnormalityMapper.getSwitchInfoWithoutNormal(feeder, kgPsrTypes);
                if(CollectionUtils.size(feederDeviceList) > 0){
                    Map<String, List<FeederDeviceVO>> collectMap = feederDeviceList.stream().collect(Collectors.groupingBy(FeederDeviceVO::getFeeder));
                    List<String> kgPsrId = feederDeviceList.stream().filter(f -> kgPsrTypes.contains(f.getPsrType())).map(FeederDeviceVO::getPsrId).collect(Collectors.toList());
                    feederSwitchMap.put(feeder,kgPsrId);
                    // 返回值处理
                    String startSwitchId = null;
                    Optional<FeederDeviceVO> first = feederDeviceList.stream().filter(f -> !StringUtils.equals("-", f.getSwitchId())).findFirst();
                    if (first.isPresent()) {
                        startSwitchId = first.get().getSwitchId();
                    }
                    List<String> endSwitchList = feederDeviceList.stream()
                            .map(FeederDeviceVO::getEndSwitchId)
                            .filter(endSwitchId -> !StringUtils.equals("-", endSwitchId)).collect(Collectors.toList());
                    List<String> midSwitchList = feederDeviceList.stream()
                            .map(FeederDeviceVO::getPsrId)
                            .filter(psrId -> !StringUtils.equals("-", psrId)).collect(Collectors.toList());
                    // 成图对应的显示开关，需要排除结尾开关和已存在的中间开关
                    List<String> switchMxList = Optional.ofNullable(feederSwitchMap.get(feeder))
                            .map(en -> en.stream().filter(s -> !endSwitchList.contains(s) && !midSwitchList.contains(s)).collect(Collectors.toList()))
                            .orElse(Lists.newArrayList());
                    BreakerAreaVO breakerArea = new BreakerAreaVO();
                    breakerArea.setIsFullLine("0").setOppositeLineId(feeder)
                            .setStartSwitch(startSwitchId)
                            .setEndSwitch(endSwitchList)
                            .setMidSwitch(ListUtils.union(midSwitchList, switchMxList));
                    breakerAreaList.add(breakerArea);
                }
            });
            if(CollectionUtils.size(breakerAreaList) > 0){
                Map<String, List<BreakerAreaVO>> listMap = breakerAreaList.stream().collect(Collectors.groupingBy(ba -> stationMap.get(ba.getOppositeLineId())));
                return new ArrayList<>(listMap.values());
            }
        }
        return Lists.newArrayList();
    }
}
