package com.njcn.device.pms.service.gwPush.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.device.pms.pojo.param.MonitorParam;
import com.njcn.device.pms.pojo.po.*;
import com.njcn.device.pms.pojo.vo.gw.*;
import com.njcn.device.pms.service.gwPush.MonitorSendService;
import com.njcn.device.pms.service.majornetwork.*;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.api.DictTreeFeignClient;
import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.enums.DicTreeEnum;
import com.njcn.system.pojo.po.DictData;
import com.njcn.system.pojo.po.SysDicTreePO;
import com.njcn.system.pojo.vo.DictTreeVO;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.pojo.vo.PvTerminalTreeVO;
import com.njcn.web.enums.GWSendEnum;
import com.njcn.web.pojo.param.SendParam;
import com.njcn.web.utils.GwSendUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * @author wr
 * @description 国网台账类上送
 * @date 2023/12/7 8:57
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class MonitorSendServiceImpl implements MonitorSendService {

    private final IMonitorService monitorService;
    private final DeptFeignClient deptFeignClient;
    private final IPowerClientService powerClientService;
    private final DicDataFeignClient dicDataFeignClient;
    private final DictTreeFeignClient dictTreeFeignClient;
    private final IPowerGenerationUserService iPowerGenerationUserService;
    private final ITractionStationService tractionStationService;
    private final IStatationStatService statationStatService;

    @Override
    public String sendType(MonitorParam.Info param) {
        SysDicTreePO dicTree;
        List<String> objTypeIds=new ArrayList<>();
        LambdaQueryWrapper<Monitor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if(param.getObjType().equals("987654321")){
            dicTree = new SysDicTreePO();
            dicTree.setCode("987654321");
            dicTree.setName("其他");

            //特殊处理
            List<SysDicTreePO> sysDicTreePOList = dictTreeFeignClient.queryAll().getData();
            List<SysDicTreePO>  typicDic =sysDicTreePOList.stream().filter(item->
                    Objects.equals(DicTreeEnum.Power_Station.getCode(),item.getCode())||
                            Objects.equals(DicTreeEnum.Ele_Railways.getCode(),item.getCode())||
                    Objects.equals(DicTreeEnum.Wind_Farms.getCode(),item.getCode())||
                            Objects.equals(DicTreeEnum.Imp_Users.getCode(),item.getCode())).collect(Collectors.toList());

            for(SysDicTreePO sysDicTreePO : typicDic){
                List<DictTreeVO> temList = dictTreeFeignClient.query(sysDicTreePO.getId()).getData();
                List<String> ids = temList.stream().map(DictTreeVO::getId).collect(Collectors.toList());
                objTypeIds.addAll(ids);
                objTypeIds.add(sysDicTreePO.getId());
            }
            lambdaQueryWrapper.notIn(Monitor::getObjType, objTypeIds);
        }else {
            dicTree = dictTreeFeignClient.queryById(param.getObjType()).getData();
            if(ObjectUtil.isNull(dicTree)){
                throw new BusinessException("请检查监测对象类型是否存在");
            }
            List<DictTreeVO> objType = dictTreeFeignClient.query(param.getObjType()).getData();
            objTypeIds.add(param.getObjType());
            if(CollUtil.isNotEmpty(objType)){
                objTypeIds.addAll(objType.stream().map(DictTreeVO::getId).collect(Collectors.toList()));
            }
            lambdaQueryWrapper.in(Monitor::getObjType, objTypeIds);
        }

        //获取监测点信息
        lambdaQueryWrapper
                .eq(Monitor::getIsUpToGrid,1)
                .in(CollUtil.isNotEmpty(param.getIds()),Monitor::getId, param.getIds());

        List<Monitor> monitorList = monitorService.list(lambdaQueryWrapper);
        if(CollUtil.isEmpty(monitorList)){
            return "国网上送监测点为空,请检查是否存在上送国网监测点";
        }
        List<String> powerIds= monitorList.stream().map(Monitor::getPowerrId).distinct().collect(Collectors.toList());
        List<StatationStat> statationStats = statationStatService.listByIds(powerIds);
        Map<String, StatationStat> powerMap = statationStats.stream().collect(Collectors
                .toMap(StatationStat::getPowerId, Function.identity()));
        for (Monitor monitor : monitorList) {
            if(powerMap.containsKey(monitor.getPowerrId())){
                monitor.setPowerrId(powerMap.get(monitor.getPowerrId()).getMidStationId());
            }else{
                monitor.setPowerrId("");
            }
        }
        return monitorType(dicTree, monitorList);
    }

    private String monitorType(SysDicTreePO dicTree, List<Monitor> monitorList) {
       StrBuilder str=new StrBuilder();
        switch (dicTree.getCode()) {
            case "1401":
                List<WindSourceDto> info = this.windSend(monitorList);
                sendSize(info);
                List<List<WindSourceDto>> split = ListUtil.split(info, 100);
                for (int i = 0; i < split.size(); i++) {
                    SendParam sendParam = new SendParam();
                    sendParam.setStats(split.get(i));
                    Map<String, String> send = GwSendUtil.send(sendParam, GWSendEnum.WIND_CREATE);
                    List<String> wiIds = info.stream().map(WindSourceDto::getId).distinct().collect(Collectors.toList());
                    str.append("第"+(i+1)+"次循环："+ returnInformation(1, wiIds, send)+";</br>");
                }
                break;
            case "1402":
                List<PhotovoltaicDto> photovoltaic = this.photovoltaicSend(monitorList);
                sendSize(photovoltaic);
                List<List<PhotovoltaicDto>> phSplit = ListUtil.split(photovoltaic, 100);
                for (int i = 0; i < phSplit.size(); i++) {
                    SendParam phSend = new SendParam();
                    phSend.setStats(phSplit.get(i));
                    Map<String, String> phMap = GwSendUtil.send(phSend, GWSendEnum.PHOTOVOLTAIC_CREATE);
                    List<String> phIds = photovoltaic.stream().map(PhotovoltaicDto::getId).distinct().collect(Collectors.toList());
                    str.append("第"+(i+1)+"次循环："+ returnInformation(1, phIds, phMap)+";</br>");
                }
                break;
            case "2400":
                List<SensitiveUserDto> sensitive = this.sensitiveUserSend(monitorList);
                sendSize(sensitive);
                List<List<SensitiveUserDto>> seSplit = ListUtil.split(sensitive, 100);
                for (int i = 0; i < seSplit.size(); i++) {
                    SendParam seSend = new SendParam();
                    seSend.setStats(seSplit.get(i));
                    Map<String, String> seMap = GwSendUtil.send(seSend, GWSendEnum.SENSITIVE_USER_CREATE);
                    List<String> seIds = sensitive.stream().map(SensitiveUserDto::getId).distinct().collect(Collectors.toList());
                    str.append("第"+(i+1)+"次循环："+ returnInformation(1, seIds, seMap)+";</br>");
                }
                break;
            case "1300":
                List<TractionStationDTO> traction = this.tractionStationSend(monitorList);
                sendSize(traction);
                List<List<TractionStationDTO>> trSplit = ListUtil.split(traction, 100);
                for (int i = 0; i < trSplit.size(); i++) {
                    SendParam trSend = new SendParam();
                    trSend.setStats(trSplit.get(i));
                    Map<String, String> trMap = GwSendUtil.send(trSend, GWSendEnum.TRACTION_STATION);
                    List<String> trIds = traction.stream().map(TractionStationDTO::getId).distinct().collect(Collectors.toList());
                    str.append("第"+(i+1)+"次循环："+ returnInformation(1, trIds, trMap)+";</br>");
                }
                break;
//            case "2300":
            default:
                List<OtherUserDto> other = this.otherUserSend(monitorList);
                sendSize(other);
                List<List<OtherUserDto>> otSplit = ListUtil.split(other, 100);
                for (int i = 0; i < otSplit.size(); i++) {
                    SendParam otSend = new SendParam();
                    otSend.setStats(otSplit.get(i));
                    Map<String, String> otMap = GwSendUtil.send(otSend, GWSendEnum.OTHER_USER_CREATE);
                    List<String> otIds = other.stream().map(OtherUserDto::getId).distinct().collect(Collectors.toList());
                    str.append("第"+(i++)+"循环："+ returnInformation(1, otIds, otMap)+";</br>");
                }
                break;
        }
        return str.toString();
    }

    private void sendSize(List info) {
        if (CollUtil.isEmpty(info)) {
            throw new BusinessException("查询数据为空,请查询数据是否存在!");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<WindSourceDto> windSend(List<Monitor> monitorList) {
        List<PvTerminalTreeVO> deptList = deptFeignClient.allDeptList().getData();
        Map<String, PvTerminalTreeVO> mapCode = deptList.stream().collect(Collectors.toMap(PvTerminalTreeVO::getCode, Function.identity()));
        Map<String, PvTerminalTreeVO> mapList = deptList.stream().collect(Collectors.toMap(PvTerminalTreeVO::getId, Function.identity()));
        //电压等级
        List<DictData> voltage = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_VOLTAGE.getCode()).getData();
        Map<String, DictData> mapVoltage = voltage.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));

        //运行状态
//        List<DictData> lineState = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.LINE_STATE.getCode()).getData();
//        Map<String, DictData> mapLineState = lineState.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));

        List<WindSourceDto> info = new ArrayList<>();
        WindSourceDto sendVO;
        for (Monitor monitor : monitorList) {
            sendVO = new WindSourceDto();
            //添加部门信息
            BeanUtil.copyProperties(setOrgProvince(mapCode, mapList, monitor.getOrgId()), sendVO);
            sendVO.setStationName(monitor.getMonitorObjectName());
            //电站等级
            if (mapVoltage.containsKey(monitor.getVoltageLevel())) {
                sendVO.setGcVoltageLevel(String.format("%02d", mapVoltage.get(monitor.getVoltageLevel()).getAlgoDescribe()));
                sendVO.setSubstationVoltageLevel(String.format("%02d", mapVoltage.get(monitor.getVoltageLevel()).getAlgoDescribe()));
            }
            sendVO.setId(monitor.getId());
            sendVO.setIsSpecial(monitor.getIsSpecialSupplyElectricity().toString());
            sendVO.setMonitorId(monitor.getMonitorId());
            sendVO.setStationCapacity(monitor.getUserAgreementCapacity());
            sendVO.setStationId(monitor.getId());
            sendVO.setSubstationId(monitor.getPowerrId());
            sendVO.setSubstationName(monitor.getPowerrName());
            sendVO.setFcId(monitor.getMonitorObjectId());
            sendVO.setFcNo(monitor.getMonitorObjectId());
            sendVO.setMonitorObjectType(monitor.getFieldStation());
            sendVO.setRunStatus("20");
            //运行状态
//            if (mapLineState.containsKey(monitor.getMonitorState())) {
//                sendVO.setRunStatus(mapLineState.get(monitor.getMonitorState()).getValue());
//            }
            sendVO.setCreateTime(monitor.getCreateTime());
            sendVO.setUpdateTime(monitor.getUpdateTime());

//            sendVO.setRatedCapacity();
//            sendVO.setDeviceCapacity();
//            sendVO.setDeviceType();
//            sendVO.setDeviceVoltageLevel();
//            sendVO.setIsSceneTest();
//            sendVO.setStationType();
//            sendVO.setSingleRatedCapacity();
//            sendVO.setWindNum();
//            sendVO.setWindStationType();
//            sendVO.setWindType();
            info.add(sendVO);
        }
        return info;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<PhotovoltaicDto> photovoltaicSend(List<Monitor> monitorList) {
        List<PvTerminalTreeVO> deptList = deptFeignClient.allDeptList().getData();
        Map<String, PvTerminalTreeVO> mapCode = deptList.stream().collect(Collectors.toMap(PvTerminalTreeVO::getCode, Function.identity()));
        Map<String, PvTerminalTreeVO> mapList = deptList.stream().collect(Collectors.toMap(PvTerminalTreeVO::getId, Function.identity()));
        //电压等级
        List<DictData> voltage = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_VOLTAGE.getCode()).getData();
        Map<String, DictData> mapVoltage = voltage.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));

        //运行状态
        List<DictData> lineState = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.LINE_STATE.getCode()).getData();
        Map<String, DictData> mapLineState = lineState.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));

        List<PhotovoltaicDto> info = new ArrayList<>();
        PhotovoltaicDto sendVO;
        for (Monitor monitor : monitorList) {
            sendVO = new PhotovoltaicDto();
            //添加部门信息
            BeanUtil.copyProperties(setOrgProvince(mapCode, mapList, monitor.getOrgId()), sendVO);
            sendVO.setStationName(monitor.getMonitorObjectName());
            //电站等级
            if (mapVoltage.containsKey(monitor.getVoltageLevel())) {
                sendVO.setGcVoltageLevel(String.format("%02d", mapVoltage.get(monitor.getVoltageLevel()).getAlgoDescribe()));
                sendVO.setSubstationVoltageLevel(String.format("%02d", mapVoltage.get(monitor.getVoltageLevel()).getAlgoDescribe()));
            }
            sendVO.setId(monitor.getId());
            sendVO.setIsSpecial(monitor.getIsSpecialSupplyElectricity().toString());
            sendVO.setMonitorId(monitor.getMonitorId());
            sendVO.setStationCapacity(monitor.getUserAgreementCapacity());
            sendVO.setStationId(monitor.getId());
            sendVO.setSubstationId(monitor.getPowerrId());
            sendVO.setSubstationName(monitor.getPowerrName());
            sendVO.setFcId(monitor.getMonitorObjectId());
            sendVO.setFcNo(monitor.getMonitorObjectId());
            sendVO.setMonitorObjectType(monitor.getFieldStation());
            sendVO.setRunStatus("20");
            //运行状态
//            if (mapLineState.containsKey(monitor.getMonitorState())) {
//                sendVO.setRunStatus(mapLineState.get(monitor.getMonitorState()).getValue());
//            }
            sendVO.setCreateTime(monitor.getCreateTime());
            sendVO.setUpdateTime(monitor.getUpdateTime());

//            sendVO.setRatedCapacity();
//            sendVO.setDeviceCapacity();
//            sendVO.setDeviceType();
//            sendVO.setDeviceVoltageLevel();
//            sendVO.setIsSceneTest();
//            sendVO.setStationType();
//            sendVO.setInverterNetWorkWay();

            info.add(sendVO);
        }
        return info;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<SensitiveUserDto> sensitiveUserSend(List<Monitor> monitorList) {

        //根据用户类型进行分组
        Map<Integer, List<String>> userMonitor = monitorList.stream().filter(x -> ObjectUtil.isNotNull(x.getIfPowerUser()))
                .collect(Collectors.groupingBy(Monitor::getIfPowerUser,
                        Collectors.mapping(Monitor::getMonitorObjectId, Collectors.toList())));
        //获取用电用户
        List<PowerClient> powerClients = new ArrayList<>();
        if (userMonitor.containsKey(0)) {
            powerClients = powerClientService.list(new LambdaQueryWrapper<PowerClient>()
                    .in(PowerClient::getId, userMonitor.get(0)));
        }
        //获取发电用户
        List<PowerGenerationUser> powerGenerationUsers = new ArrayList<>();
        if (userMonitor.containsKey(1)) {
            powerGenerationUsers = iPowerGenerationUserService.list(new LambdaQueryWrapper<PowerGenerationUser>()
                    .in(PowerGenerationUser::getId, userMonitor.get(1)));
        }
        //用户分类
        List<DictData> userClass = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.USER_CLASS.getCode()).getData();
        Map<String, DictData> mapUserClass = userClass.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));

        //电压等级
        List<DictData> voltage = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_VOLTAGE.getCode()).getData();
        Map<String, DictData> mapVoltage = voltage.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));

        //电压等级
        List<DictData> eleClass = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.ELE_CLASS.getCode()).getData();
        Map<String, DictData> mapEleClass = eleClass.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));

        //行业分类
        List<DictData> industryType = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.INDUSTRY_TYPE.getCode()).getData();
        Map<String, DictData> mapIndustryType = industryType.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));

        //重要性等级
        List<DictData> importanceLevel = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.IMPORTANCE_LEVEL.getCode()).getData();
        Map<String, DictData> mapImportanceLevel = importanceLevel.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));
//        //运行状态
//        List<DictData> lineState = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.LINE_STATE.getCode()).getData();
//        Map<String, DictData> mapLineState = lineState.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));

        List<SensitiveUserDto> info = new ArrayList<>();
        SensitiveUserDto sendVO;
        List<PvTerminalTreeVO> deptList = deptFeignClient.allDeptList().getData();
        Map<String, PvTerminalTreeVO> mapCode = deptList.stream().collect(Collectors.toMap(PvTerminalTreeVO::getCode, Function.identity()));
        Map<String, PvTerminalTreeVO> mapList = deptList.stream().collect(Collectors.toMap(PvTerminalTreeVO::getId, Function.identity()));
        for (Monitor monitor : monitorList) {
            sendVO = new SensitiveUserDto();
            PvTerminalTreeVO pvTerminalTreeVO;
            //添加部门信息
            BeanUtil.copyProperties(setOrgProvince(mapCode, mapList, monitor.getOrgId()), sendVO);
            sendVO.setId(monitor.getId());

            if (mapCode.containsKey(monitor.getOperationId())) {
                pvTerminalTreeVO = mapCode.get(monitor.getOperationId());
                sendVO.setMaintGroupName(pvTerminalTreeVO.getName());
                sendVO.setMaintGroupId(pvTerminalTreeVO.getCode());
            }
            sendVO.setSensitiveUserName(monitor.getName());
            sendVO.setUserProtocolCapacity(monitor.getUserAgreementCapacity());
            sendVO.setMonitorId(monitor.getMonitorId());
            sendVO.setStationId(monitor.getPowerrId());
            sendVO.setStationName(monitor.getPowerrName());
            sendVO.setPubPrivFlag(monitor.getIsSpecialMonitor() + "");
            sendVO.setRunStatus("20");
            //运行状态
//            if (mapLineState.containsKey(monitor.getMonitorState())) {
//                sendVO.setRunStatus(mapLineState.get(monitor.getMonitorState()).getValue());
//            }
            sendVO.setCreateTime(monitor.getCreateTime());
            sendVO.setUpdateTime(monitor.getUpdateTime());
            if (mapVoltage.containsKey(monitor.getVoltageLevel())) {
                sendVO.setStationVoltageLevel(String.format("%02d", mapVoltage.get(monitor.getVoltageLevel()).getAlgoDescribe()));
                sendVO.setConsVoltageLevel(String.format("%02d", mapVoltage.get(monitor.getVoltageLevel()).getAlgoDescribe()));
            }
            //行业分类
            if (mapIndustryType.containsKey(monitor.getTradeCode())) {
                DictData dictData = mapIndustryType.get(monitor.getTradeCode());
                sendVO.setTradeCode(dictData.getValue());
            }
            if (ObjectUtil.isNotNull(monitor.getIfPowerUser())) {
                setSensitiveUser(powerClients, powerGenerationUsers, mapVoltage, mapUserClass, mapEleClass, mapImportanceLevel, sendVO, monitor);
            }


//            sendVO.setMeterAddress();
//            sendVO.setTradeCode();
//
//            sendVO.setFeederId();
//            sendVO.setFeederName();
//            sendVO.setTransId();
//            sendVO.setTransName();
//            sendVO.setTransType();
//            sendVO.setTransNature();
//            sendVO.setMaintOrg();

//            sendVO.setHighRkType();
//            sendVO.setFcGcFlag();
//            sendVO.setGcTypeCode();
//            sendVO.setProblemDesc();
//            sendVO.setOcDate();
//            sendVO.setIsMonitoringOnline();
//            sendVO.setHaveDevice();
//            sendVO.setDeviceType();
//            sendVO.setDeviceVoltageLevel();
//            sendVO.setDeviceCapacity();
//            sendVO.setComplaintDate();
//            sendVO.setComplaintContent();
//            sendVO.setModifyMethods();
//            sendVO.setHaveComplaint();
//            sendVO.setHavePowerQualityProblem();
//            sendVO.setStationType();

            info.add(sendVO);
        }
        return info;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<TractionStationDTO>  tractionStationSend(List<Monitor> monitorList) {
        //获取已存在牵引站的信息
        List<String> tractionIds = monitorList.stream().map(Monitor::getTractionId).collect(Collectors.toList());
        List<TractionStation> tractionStationList = tractionStationService.list(new LambdaQueryWrapper<TractionStation>()
                .in(TractionStation::getId, tractionIds));
        Map<String, TractionStation> tractionMap = tractionStationList.stream().collect(Collectors.toMap(TractionStation::getId, Function.identity()));

        List<TractionStationDTO> info = new ArrayList<>();
        TractionStationDTO sendVO;
        List<PvTerminalTreeVO> deptList = deptFeignClient.allDeptList().getData();
        Map<String, PvTerminalTreeVO> mapCode = deptList.stream().collect(Collectors.toMap(PvTerminalTreeVO::getCode, Function.identity()));
        Map<String, PvTerminalTreeVO> mapList = deptList.stream().collect(Collectors.toMap(PvTerminalTreeVO::getId, Function.identity()));
        //牵引站变压器接线方式
        List<DictData> connetGroupWay = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.CONNET_GROUP_WAY.getCode()).getData();
        Map<String, DictData> mapConnetGroupWay = connetGroupWay.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));
        //运行状态
//        List<DictData> lineState = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.LINE_STATE.getCode()).getData();
//        Map<String, DictData> mapLineState = lineState.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));
        //电压等级
        List<DictData> voltage = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_VOLTAGE.getCode()).getData();
        Map<String, DictData> mapVoltage = voltage.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));

        TractionStation traction;
        for (Monitor monitor : monitorList) {
            sendVO = new TractionStationDTO();
            DictData dictData;
            //添加部门信息
            BeanUtil.copyProperties(setOrgProvince(mapCode, mapList, monitor.getOrgId()), sendVO);
            if(tractionMap.containsKey(monitor.getTractionId())){
                traction = tractionMap.get(monitor.getTractionId());
                //牵引站变压器接线方式
                if (mapConnetGroupWay.containsKey(traction.getConnetGroupWay())) {
                    dictData = mapConnetGroupWay.get(traction.getConnetGroupWay());
                    sendVO.setConnetGroupWay(dictData.getValue());
                }
                sendVO.setIfSpecial(traction.getIfSpecial() + "");
                sendVO.setTractionName(traction.getName());
                sendVO.setRailwayName(traction.getRailwayLineName());
                sendVO.setRailwayType(traction.getRailwayType());
                sendVO.setRailwayNumber(traction.getRailwayLineId());
                sendVO.setTractionCode(traction.getId());
                sendVO.setTractionSubCapacity(BigDecimal.valueOf(traction.getRatedCapacity()));
                sendVO.setTractionSubstationId(monitor.getPowerrId());
                sendVO.setTractionSubstationName(monitor.getPowerrName());
                sendVO.setMainSubstationId(monitor.getPowerrId());
                sendVO.setMainSubstationName(monitor.getPowerrName());
                //电压等级
                if (mapVoltage.containsKey(traction.getVoltageLevel())) {
                    sendVO.setTractionVoltageLevel(String.format("%02d", mapVoltage.get(traction.getVoltageLevel()).getAlgoDescribe()));
                    sendVO.setMainVolatageLevel(String.format("%02d", mapVoltage.get(traction.getVoltageLevel()).getAlgoDescribe()));
                }
            }else{
                if (mapVoltage.containsKey(monitor.getVoltageLevel())) {
                    sendVO.setTractionVoltageLevel(String.format("%02d", mapVoltage.get(monitor.getVoltageLevel()).getAlgoDescribe()));
                    sendVO.setMainVolatageLevel(String.format("%02d", mapVoltage.get(monitor.getVoltageLevel()).getAlgoDescribe()));
                }
                sendVO.setTractionSubstationId(monitor.getPowerrId());
                sendVO.setTractionSubstationName(monitor.getPowerrName());
                sendVO.setMainSubstationId(monitor.getPowerrId());
                sendVO.setMainSubstationName(monitor.getPowerrName());
            }
            sendVO.setCreateTime(monitor.getCreateTime());
            sendVO.setUpdateTime(monitor.getUpdateTime());
            sendVO.setId(monitor.getId());
            sendVO.setMonitorName(monitor.getName());
            sendVO.setMonitorNumber(monitor.getMonitorId());
            sendVO.setRunStatus("20");
            //运行状态
//            if (mapLineState.containsKey(monitor.getMonitorState())) {
//                sendVO.setRunStatus(mapLineState.get(monitor.getMonitorState()).getValue());
//            }


//            sendVO.setAuxiliarySubstationId();
//            sendVO.setAuxiliarySubstationName();
//            sendVO.setAuxiliaryVoltageLevel();
//            sendVO.setCableCoresNum();
//            sendVO.setCableLayingMethod();
//            sendVO.setCableModel();
//            sendVO.setCableRouteLength();

//            sendVO.setMonitorNumberTwo();
//            sendVO.setRailwayType();
//            sendVO.setTransformerConnectionGroupMethod();
//            sendVO.setTransformerNameplateCapacity();
//            sendVO.setTransformerOneVoltageLevel();
//            sendVO.setTransformerTwoVoltageLevel();
//            sendVO.setTriphaseVvNameplateCapacity();
//            sendVO.setUploadDate();
            info.add(sendVO);
        }
        return info;
    }

    @Override
    public List<OtherUserDto> otherUserSend(List<Monitor> monitorList) {
        List<PvTerminalTreeVO> deptList = deptFeignClient.allDeptList().getData();
        Map<String, PvTerminalTreeVO> mapCode = deptList.stream().collect(Collectors.toMap(PvTerminalTreeVO::getCode, Function.identity()));
        Map<String, PvTerminalTreeVO> mapList = deptList.stream().collect(Collectors.toMap(PvTerminalTreeVO::getId, Function.identity()));
        //电压等级
        List<DictData> voltage = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_VOLTAGE.getCode()).getData();
        Map<String, DictData> mapVoltage = voltage.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));
        //运行状态
//        List<DictData> lineState = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.LINE_STATE.getCode()).getData();
//        Map<String, DictData> mapLineState = lineState.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));
        //行业分类
        List<DictData> industryType = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.INDUSTRY_TYPE.getCode()).getData();
        Map<String, DictData> mapIndustryType = industryType.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));
        List<OtherUserDto> info = new ArrayList<>();
        OtherUserDto dto;
        for (Monitor monitor : monitorList) {
            dto = new OtherUserDto();
            PvTerminalTreeVO pvTerminalTreeVO;
            BeanUtil.copyProperties(setOrgProvince(mapCode, mapList, monitor.getOrgId()), dto);
            dto.setId(monitor.getId());
            if (mapCode.containsKey(monitor.getOperationId())) {
                pvTerminalTreeVO = mapCode.get(monitor.getOperationId());
                dto.setMaintOrgName(pvTerminalTreeVO.getName());
                dto.setMaintOrg(pvTerminalTreeVO.getCode());
            }
            dto.setConsNo(monitor.getId());
            dto.setConsName(monitor.getName());
            //电压等级
            if (mapVoltage.containsKey(monitor.getVoltageLevel())) {
                dto.setGcVoltageLevel(String.format("%02d", mapVoltage.get(monitor.getVoltageLevel()).getAlgoDescribe()));
                dto.setSubstationVoltageLevel(String.format("%02d", mapVoltage.get(monitor.getVoltageLevel()).getAlgoDescribe()));
            }
            dto.setSubstationId(monitor.getPowerrId());
            dto.setSubstationName(monitor.getPowerrName());
            //行业分类
            if (mapIndustryType.containsKey(monitor.getTradeCode())) {
                dto.setTradeCode(mapIndustryType.get(monitor.getTradeCode()).getValue());
            }
            dto.setProtocolCapacity(monitor.getUserAgreementCapacity());
            dto.setMonitorId(monitor.getMonitorId());
//            dto.setIsMonitoringOnline();
//            dto.setIsSceneTest();
//            dto.setHaveDevice();
//            dto.setDeviceType();
//            dto.setDeviceVoltageLevel();
//            dto.setDeviceCapacity();
            dto.setRunStatus("20");
            //运行状态
//            if (mapLineState.containsKey(monitor.getMonitorState())) {
//                dto.setRunStatus(mapLineState.get(monitor.getMonitorState()).getValue());
//            }
            dto.setCreateTime(monitor.getCreateTime());
            dto.setUpdateTime(monitor.getUpdateTime());
            info.add(dto);
        }
        return info;
    }

    @Override
    public void exportSend(HttpServletResponse response) throws IOException {
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), WindSourceDto.class).build();

        List<WindSourceDto> wind = this.windSend(getMonitors(dictTreeFeignClient.queryByCode(DicTreeEnum.Wind_Farms.getCode()).getData().getId()));
        WriteSheet writeSheet = EasyExcel.writerSheet(0, "风电场" ).head(WindSourceDto.class).build();
        excelWriter.write(wind, writeSheet);

        List<PhotovoltaicDto> photovoltaic = this.photovoltaicSend(getMonitors(dictTreeFeignClient.queryByCode(DicTreeEnum.Power_Station.getCode()).getData().getId()));
        WriteSheet writeSheet2 = EasyExcel.writerSheet(1, "光伏电站" ).head(PhotovoltaicDto.class).build();
        excelWriter.write(photovoltaic, writeSheet2);

        List<SensitiveUserDto> sensitive = this.sensitiveUserSend(getMonitors(dictTreeFeignClient.queryByCode(DicTreeEnum.Imp_Users.getCode()).getData().getId()));
        WriteSheet writeSheet3 = EasyExcel.writerSheet(2, "重要或敏感用户" ).head(SensitiveUserDto.class).build();
        excelWriter.write(sensitive, writeSheet3);

        List<TractionStationDTO> traction = this.tractionStationSend(getMonitors(dictTreeFeignClient.queryByCode(DicTreeEnum.Ele_Railways.getCode()).getData().getId()));
        WriteSheet writeSheet4 = EasyExcel.writerSheet(3, "牵引站" ).head(TractionStationDTO.class).build();
        excelWriter.write(traction, writeSheet4);

        List<OtherUserDto> other = this.otherUserSend(getMonitors("987654321"));
        WriteSheet writeSheet5 = EasyExcel.writerSheet(4, "干扰用户" ).head(OtherUserDto.class).build();
        excelWriter.write(other, writeSheet5);
        excelWriter.finish();
    }

    private List<Monitor> getMonitors(String id) {
        SysDicTreePO dicTree;
        List<String> objTypeIds=new ArrayList<>();
        LambdaQueryWrapper<Monitor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if(id.equals("987654321")){
            dicTree = new SysDicTreePO();
            dicTree.setCode("987654321");
            dicTree.setName("其他");

            //特殊处理
            List<SysDicTreePO> sysDicTreePOList = dictTreeFeignClient.queryAll().getData();
            List<SysDicTreePO>  typicDic =sysDicTreePOList.stream().filter(item-> Objects.equals(DicTreeEnum.Power_Station.getCode(),item.getCode())||Objects.equals(DicTreeEnum.Ele_Railways.getCode(),item.getCode())||
                    Objects.equals(DicTreeEnum.Wind_Farms.getCode(),item.getCode())||Objects.equals(DicTreeEnum.Imp_Users.getCode(),item.getCode())).collect(Collectors.toList());

            for(SysDicTreePO sysDicTreePO : typicDic){
                List<DictTreeVO> temList = dictTreeFeignClient.query(sysDicTreePO.getId()).getData();
                List<String> ids = temList.stream().map(DictTreeVO::getId).collect(Collectors.toList());
                objTypeIds.addAll(ids);
                objTypeIds.add(sysDicTreePO.getId());
            }
            lambdaQueryWrapper.notIn(Monitor::getObjType, objTypeIds);
        }else {
            dicTree = dictTreeFeignClient.queryById(id).getData();
            if(ObjectUtil.isNull(dicTree)){
                throw new BusinessException("请检查监测对象类型是否存在");
            }
            List<DictTreeVO> objType = dictTreeFeignClient.query(id).getData();
            objTypeIds.add(id);
            if(CollUtil.isNotEmpty(objType)){
                objTypeIds.addAll(objType.stream().map(DictTreeVO::getId).collect(Collectors.toList()));
            }
            lambdaQueryWrapper.in(Monitor::getObjType, objTypeIds);
        }
        //获取监测点信息
        lambdaQueryWrapper
                .eq(Monitor::getIsUpToGrid,1);

        List<Monitor> monitorList = monitorService.list(lambdaQueryWrapper);
        List<String> powerIds= monitorList.stream().map(Monitor::getPowerrId).distinct().collect(Collectors.toList());
        List<StatationStat> statationStats = statationStatService.listByIds(powerIds);
        Map<String, StatationStat> powerMap = statationStats.stream().collect(Collectors
                .toMap(StatationStat::getPowerId, Function.identity()));
        for (Monitor monitor : monitorList) {
            if(powerMap.containsKey(monitor.getPowerrId())){
                monitor.setPowerrId(powerMap.get(monitor.getPowerrId()).getMidStationId());
            }else{
                monitor.setPowerrId("");
            }
        }
        return monitorList;
    }

    /**
     * 省市县，对象添加
     *
     * @param mapCode
     * @param mapList
     * @param orgId
     * @return
     */
    private Unit setOrgProvince(Map<String, PvTerminalTreeVO> mapCode, Map<String, PvTerminalTreeVO> mapList, String orgId) {
        Unit unit = new Unit();
        if (mapCode.containsKey(orgId)) {
            PvTerminalTreeVO pvTerminalTreeVO = mapCode.get(orgId);
            String[] split = (pvTerminalTreeVO.getPids() + StrUtil.COMMA + pvTerminalTreeVO.getId())
                    .split(StrUtil.COMMA);
            for (int i = 2; i < split.length; i++) {
                if (i == 2) {
                    if (mapList.containsKey(split[i])) {
                        pvTerminalTreeVO = mapList.get(split[i]);
                        unit.setProvinceName(pvTerminalTreeVO.getName());
                        unit.setProvinceId(pvTerminalTreeVO.getCode());
                    }
                }
                if (i == 3) {
                    if (mapList.containsKey(split[i])) {
                        pvTerminalTreeVO = mapList.get(split[i]);
                        unit.setCityName(pvTerminalTreeVO.getName());
                        unit.setCityId(pvTerminalTreeVO.getCode());
                    }
                }
                if (i == 4) {
                    if (mapList.containsKey(split[i])) {
                        pvTerminalTreeVO = mapList.get(split[i]);
                        unit.setCountyName(pvTerminalTreeVO.getName());
                        unit.setCountyId(pvTerminalTreeVO.getCode());
                    }
                }
            }
        }
        return unit;
    }


    /**
     * 重要敏感用户对象属性添加
     *
     * @param powerClients       发电用户
     * @param mapUserClass
     * @param mapEleClass
     * @param mapImportanceLevel
     * @param mapImportanceLevel
     * @param sendVO
     * @param monitor
     */
    private void setSensitiveUser(List<PowerClient> powerClients, List<PowerGenerationUser> powerGenerationUsers, Map<String, DictData> mapVoltage, Map<String, DictData> mapUserClass, Map<String, DictData> mapEleClass, Map<String, DictData> mapImportanceLevel, SensitiveUserDto sendVO, Monitor monitor) {
        DictData dictData;
        if (1 == monitor.getIfPowerUser()) {
            List<PowerClient> powerClientList = powerClients.stream()
                    .filter(x -> x.getId().equals(monitor.getMonitorObjectId()))
                    .collect(Collectors.toList());
            if (CollUtil.isNotEmpty(powerClientList)) {
                PowerClient powerClient = powerClientList.get(0);
                //用户类型
                if (mapUserClass.containsKey(powerClient.getUserType())) {
                    dictData = mapUserClass.get(powerClient.getUserType());
                    sendVO.setConsNo(dictData.getId());
                    sendVO.setConsSort(dictData.getValue());
                }
                //用电类别
                if (mapEleClass.containsKey(powerClient.getElectricityType())) {
                    dictData = mapEleClass.get(powerClient.getElectricityType());
                    sendVO.setElecTypeCode(dictData.getValue());
                }
                //重要性等级
                if (mapImportanceLevel.containsKey(powerClient.getImportanceLevel())) {
                    dictData = mapImportanceLevel.get(powerClient.getImportanceLevel());
                    sendVO.setCustImportance(dictData.getValue());
                }
                //用户电压等级
                if (mapVoltage.containsKey(powerClient.getVoltageLevel())) {
                    dictData = mapVoltage.get(powerClient.getVoltageLevel());
                    sendVO.setConsVoltageLevel(dictData.getValue());
                }
            }
        } else {
            List<PowerGenerationUser> powerGenerationUserList = powerGenerationUsers.stream()
                    .filter(x -> x.getId().equals(monitor.getMonitorObjectId()))
                    .collect(Collectors.toList());
            if (CollUtil.isNotEmpty(powerGenerationUserList)) {
                PowerGenerationUser powerGenerationUser = powerGenerationUserList.get(0);
                //用户电压等级
                if (mapVoltage.containsKey(powerGenerationUser.getVoltageLevel())) {
                    dictData = mapVoltage.get(powerGenerationUser.getVoltageLevel());
                    sendVO.setConsVoltageLevel(dictData.getValue());
                }
            }
        }
    }

    /**
     * 国网上送返回信息
     *
     * @param num
     * @param ids
     * @param send
     * @return
     */
    private String returnInformation(Integer num, List<String> ids, Map<String, String> send) {
        if (send.containsKey("succeed")) {
            String succeed = send.get("succeed");
            if (succeed.indexOf("\\\"") != -1) {
                succeed = succeed.replace("\\\"", "\"");
            }
            Map mapData = JSON.parseObject(succeed, Map.class);
            String status = mapData.get("status").toString();
            if ("000000".equals(status)) {
                //修改信息状态
                updateIsUploadHead(num, ids);
                String result = mapData.get("result").toString();
                Map mapCount = JSON.parseObject(result, Map.class);
                String count = mapCount.get("count").toString();
                return "操作成功:成功数据" + count + "条";
            } else {
                String errors = mapData.get("errors").toString();
                throw new BusinessException("操作失败:" + status + "_" + errors);
            }
        } else {
            throw new BusinessException("当前时间段国网上送请求过多，请稍后再试");
        }
    }

    /**
     * 修改上送信息状态
     *
     * @param num
     * @param ids id集合
     */
    private void updateIsUploadHead(Integer num, List<String> ids) {
        switch (num) {
            case 1:
                monitorService.update(new LambdaUpdateWrapper<Monitor>()
                        .set(Monitor::getIsUploadHead, 1)
                        .in(Monitor::getId, ids)
                );
                break;
            default:
                break;
        }
    }

}
