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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.device.biz.pojo.dto.DeptGetBase;
import com.njcn.device.biz.pojo.dto.DeptGetChildrenMoreDTO;
import com.njcn.device.biz.pojo.dto.LineDevGetDTO;
import com.njcn.device.biz.pojo.param.DeptGetLineParam;
import com.njcn.device.pms.mapper.majornetwork.MonitorMapper;
import com.njcn.device.pms.mapper.majornetwork.PmsGeneratrixWireMapper;
import com.njcn.device.pms.mapper.majornetwork.RStatIntegrityDMapper;
import com.njcn.device.pms.mapper.majornetwork.StatationStatMapper;
import com.njcn.device.pms.pojo.param.TerminalQueryParam;
import com.njcn.device.pms.pojo.param.gw.GwStatisticalParam;
import com.njcn.device.pms.pojo.param.gw.GwTerminalParam;
import com.njcn.device.pms.pojo.po.*;
import com.njcn.device.pms.pojo.vo.gw.MonitorEnergy;
import com.njcn.device.pms.pojo.vo.gw.Statistical;
import com.njcn.device.pms.service.gwPush.IPmsNewEnergyService;
import com.njcn.device.pms.service.gwPush.MonitorStatisticsService;
import com.njcn.device.pms.service.ledgerManger.CommTerminalService;
import com.njcn.device.pms.service.majornetwork.ITerminalService;
import com.njcn.device.pms.service.majornetwork.ITractionStationService;
import com.njcn.device.pq.pojo.vo.RStatIntegrityVO;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.api.DictTreeFeignClient;
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.dto.DeptDTO;
import com.njcn.web.pojo.dto.PmsPage;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * pqs
 *
 * @author cdf
 * @date 2023/12/11
 */
@Service
@RequiredArgsConstructor
public class MonitorStatisticsServiceImpl implements MonitorStatisticsService {

    private final CommTerminalService commTerminalService;
    private final DictTreeFeignClient dictTreeFeignClient;
    private final IPmsNewEnergyService pmsNewEnergyService;
    private final MonitorMapper monitorMapper;
    private final DeptFeignClient deptFeignClient;
    private final DicDataFeignClient dicDataFeignClient;
    private final RStatIntegrityDMapper integrityDMapper;
    private final PmsGeneratrixWireMapper generatrixWireMapper;
    private final StatationStatMapper statationStatMapper;
    private final ITractionStationService tractionStationService;
    private final ITerminalService terminalService;

    @Override
    public List<List<String>> getGwMonitorStatistics(String deptId,Integer up) {
        List<List<String>> info = new ArrayList<>();
        //查询所有一级树字典
        List<SysDicTreePO> sysDicTreePOList = dictTreeFeignClient.queryAll().getData();

        //监测点大类
        List<SysDicTreePO> broadCategory = sysDicTreePOList.stream()
                .filter(item -> Objects.equals(item.getPid(), "0"))
                .filter(item -> !Objects.equals(item.getCode(), DicDataTypeEnum.DEVICE_UNIT.getCode()))
                .collect(Collectors.toList());
        broadCategory.sort(Comparator.comparing(SysDicTreePO::getSort));

        List<String> list = new ArrayList<>();
        list.add("");
        List<String> collect = broadCategory.stream().map(SysDicTreePO::getName).collect(Collectors.toList());
        list.addAll(collect);
        list.add("合计");
        //获取主网监测统计
        Map<String, List<String>> metWorkMap = mapDicIds(broadCategory, sysDicTreePOList);

        //筛选典型源荷统计
        List<SysDicTreePO> sourceLoad = 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());
        sourceLoad.sort(Comparator.comparing(SysDicTreePO::getSort));
        //获取典型源荷监测统计
        Map<String, List<String>> sourceLoadMap = mapDicIds(sourceLoad, sysDicTreePOList);
        list.addAll(sourceLoad.stream().map(SysDicTreePO::getName).collect(Collectors.toList()));
        list.add("其他");
        list.add("合计");
        info.add(list);
        //筛选出国网统计信息
        DeptGetLineParam deptGetLineParam = new DeptGetLineParam();
        deptGetLineParam.setDeptId(deptId);
        deptGetLineParam.setMonitorStateRunning(false);
        deptGetLineParam.setSystemType(0);
        List<DeptGetChildrenMoreDTO> deptGetChildrenMoreDTOS = commTerminalService.deptGetLine(deptGetLineParam);
        //部门信息循环
        List<String> line;
        for (DeptGetChildrenMoreDTO deptMonitor : deptGetChildrenMoreDTOS) {
            line = new ArrayList<>();
            line.add(deptMonitor.getUnitName());
            List<LineDevGetDTO> lineBaseList = deptMonitor.getLineBaseList();
            if (CollUtil.isEmpty(lineBaseList)) {
                continue;
            }
            List<LineDevGetDTO> upToGridList;
            if(Objects.isNull(up) || up == 1){
               upToGridList = lineBaseList.stream().filter(item -> Objects.equals(item.getIsUpToGrid(), DataStateEnum.ENABLE.getCode())).collect(Collectors.toList());
            }else {
                upToGridList = lineBaseList;
            }
            addmetWorkList(metWorkMap, upToGridList, line);
            addSourceLoadList(sourceLoadMap, upToGridList, line);
            info.add(line);
        }
        return info;
    }

    @Override
    public List<List<String>> objTypeStatistic(String deptId) {
        List<List<String>> info = new ArrayList<>();
        //查询所有一级树字典
        List<SysDicTreePO> sysDicTreePOList = dictTreeFeignClient.queryAll().getData();

        //监测点大类
        List<SysDicTreePO> broadCategory = sysDicTreePOList.stream()
                .filter(item -> Objects.equals(item.getPid(), "0"))
                .filter(item -> !Objects.equals(item.getCode(), DicDataTypeEnum.DEVICE_UNIT.getCode()))
                .collect(Collectors.toList());
        broadCategory.sort(Comparator.comparing(SysDicTreePO::getSort));

        List<String> list = new ArrayList<>();
        list.add("单位");
        List<String> collect = broadCategory.stream().map(SysDicTreePO::getName).collect(Collectors.toList());
        list.addAll(collect);
        list.add("合计");
        //获取主网监测统计
        Map<String, List<String>> metWorkMap = mapDicIds(broadCategory, sysDicTreePOList);
        info.add(list);

        TerminalQueryParam baseParam = new TerminalQueryParam();
        List<Monitor> monitorList = monitorMapper.getAllObjUser(baseParam);
        //筛选出国网统计信息
        DeptGetLineParam deptGetLineParam = new DeptGetLineParam();
        deptGetLineParam.setDeptId(deptId);
        deptGetLineParam.setMonitorStateRunning(false);
        deptGetLineParam.setSystemType(0);
        List<DeptGetBase> deptGetChildrenMoreDTOS = commTerminalService.getDeptChildrenByParent(deptGetLineParam);
        //部门信息循环
        for (DeptGetBase dept : deptGetChildrenMoreDTOS) {
            List<String> line = new ArrayList<>();
            line.add(dept.getUnitName());
            List<String> deptIds = dept.getUnitChildrenList();
            if (CollUtil.isEmpty(deptIds)) {
                continue;
            }
            List<Monitor>  temList = monitorList.stream().filter(it->deptIds.contains(it.getOrgId())).collect(Collectors.toList());
            metWorkMap.forEach((k,v)->{
                long count = temList.stream().filter(i->v.contains(i.getObjType())).count();
                line.add(String.valueOf(count));
            });
            info.add(line);
        }
        return info;
    }

    @Override
    public List<MonitorEnergy> getGwMonitorEnergy(String deptId) {
        List<DictData> data = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_VOLTAGE.getCode()).getData();

        List<List<String>> voltage = new ArrayList<>();
        //220kv电压等级
        List<String> than220kv = data.stream().filter(x -> Double.valueOf(x.getValue()) == 220).map(DictData::getId).collect(Collectors.toList());
        //110kv电压等级
        List<String> than110kv = data.stream().filter(x -> Double.valueOf(x.getValue()) == 110).map(DictData::getId).collect(Collectors.toList());

        //大于110kv电压等级
        List<String> greaterThan110kv = data.stream().filter(x -> Double.valueOf(x.getValue()) >= 110).map(DictData::getId).collect(Collectors.toList());
        //小于于110kv电压等级
        List<String> lessThan110kv = data.stream().filter(x -> Double.valueOf(x.getValue()) < 110).map(DictData::getId).collect(Collectors.toList());
        voltage.add(than220kv);
        voltage.add(than110kv);
        voltage.add(lessThan110kv);
        List<String> totalVoltage = new ArrayList<>();
        totalVoltage.addAll(than220kv);
        totalVoltage.addAll(than110kv);
        totalVoltage.addAll(lessThan110kv);
        voltage.add(totalVoltage);

        List<MonitorEnergy> monitorEnergyList = new ArrayList<>();

        //根据部门进行分组
        List<DeptGetBase> deptChildrenByParent = getDeptChildrenByParent(deptId);
        MonitorEnergy monitorEnergy;
        List<MonitorEnergy.Details> list;
        //查询所有一级树字典
        List<DictTreeVO> dictTreeVOS = new ArrayList<>();
        DictTreeVO powerStation = dictTreeFeignClient.queryByCode(DicTreeEnum.Power_Station.getCode()).getData();
        DictTreeVO windFarms = dictTreeFeignClient.queryByCode(DicTreeEnum.Wind_Farms.getCode()).getData();
        dictTreeVOS.add(powerStation);
        dictTreeVOS.add(windFarms);
        for (DeptGetBase pmsGeneralDeviceDTO : deptChildrenByParent) {
            monitorEnergy = new MonitorEnergy();
            list = new ArrayList<>();
            monitorEnergy.setOrgName(pmsGeneralDeviceDTO.getUnitName());
            List<Monitor> monitors = monitorMapper.selectMonitorAndNewEnergy(pmsGeneralDeviceDTO.getUnitChildrenList(), Arrays.asList(powerStation.getId(), windFarms.getId()));
            //获取场站台账信息
            List<PmsNewEnergy> newEnergies = pmsNewEnergyService.list(new LambdaQueryWrapper<PmsNewEnergy>()
                    .in(PmsNewEnergy::getObjType, Arrays.asList(powerStation.getId(), windFarms.getId()))
                    .in(PmsNewEnergy::getOrgId, pmsGeneralDeviceDTO.getUnitChildrenList())
            );
            for (DictTreeVO dictTreeVO : dictTreeVOS) {
                List<Monitor> powerStationMonitors = monitors.stream().filter(x -> x.getObjType().equals(dictTreeVO.getId())).collect(Collectors.toList());
                List<PmsNewEnergy> powerStationEnergies = newEnergies.stream().filter(x -> x.getObjType().equals(dictTreeVO.getId())).collect(Collectors.toList());

                MonitorEnergy.Details details = new MonitorEnergy.Details();
                details.setObjType(dictTreeVO.getName());
                long count = powerStationMonitors.stream().filter(x -> greaterThan110kv.contains(x.getVoltageLevel())).map(Monitor::getPowerrId).distinct().count();
                details.setNum(count);

                List<MonitorEnergy.VoltageInfo> voltageInfos = new ArrayList<>();
                for (List<String> strings : voltage) {
                    MonitorEnergy.VoltageInfo info = new MonitorEnergy.VoltageInfo();
                    long monitorNum = powerStationMonitors.stream().filter(x -> strings.contains(x.getVoltageLevel())).map(Monitor::getTractionId).distinct().count();
                    info.setMonitorNum(monitorNum);
                    long totalNum = powerStationEnergies.stream().filter(x -> strings.contains(x.getVoltageLevel())).map(PmsNewEnergy::getId).distinct().count();
                    info.setTotalNum(totalNum);
                    info.setMonitorRate(totalNum == 0 ? 0 : NumberUtil.div(monitorNum * 100.0, totalNum, 2));
                    long deviceNum = powerStationMonitors.stream().filter(x -> strings.contains(x.getVoltageLevel())).map(Monitor::getTerminalId).distinct().count();
                    info.setDeviceNum(deviceNum);
                    long SubsNum = powerStationMonitors.stream().filter(x -> strings.contains(x.getVoltageLevel())).map(Monitor::getPowerrId).distinct().count();
                    long SubstationsNum = powerStationEnergies.stream().filter(x -> strings.contains(x.getVoltageLevel())).map(PmsNewEnergy::getPowerrName).distinct().count();
                    info.setSubstationsNum(SubstationsNum);
                    info.setSubstationsRate(SubstationsNum == 0 ? 0 : NumberUtil.div(SubsNum * 100.0, SubstationsNum, 2));
                    voltageInfos.add(info);
                }

                details.setVoltageInfo(voltageInfos);
                list.add(details);
                monitorEnergy.setInfo(list);
            }
            monitorEnergyList.add(monitorEnergy);
        }
        return monitorEnergyList;
    }

    @Override
    public PmsPage<Map<String, String>> getMonitorTerminalData(GwTerminalParam param) {

        //终端状态
        List<DictData> devStatus = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_STATUS.getCode()).getData();
        List<String> devStatusIds = devStatus.stream().filter(x -> param.getDeployState().contains(x.getValue())).map(DictData::getId).collect(Collectors.toList());
        Map<String, DictData> mapDevStatus = devStatus.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));


        //测量信号输入形式
        List<DictData> signal = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.INPUT_SIGNAL.getCode()).getData();
        Map<String, DictData> mapSignal = signal.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));

        //生产厂家
        List<DictData> manufacture = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_MANUFACTURER.getCode()).getData();
        Map<String, DictData> mapManufacture = manufacture.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));


        LambdaQueryWrapper<Monitor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(Monitor::getTerminalId);
        lambdaQueryWrapper.eq(Monitor::getIsUpToGrid, 1);
        List<Monitor> monitors = monitorMapper.selectList( lambdaQueryWrapper);

        List<String> terminalIds = monitors.stream().map(Monitor::getTerminalId).collect(Collectors.toList());
        Page<PmsTerminal> page = terminalService.page(new Page<>(param.getPageNum(), param.getPageSize()),
                new LambdaQueryWrapper<PmsTerminal>()
                        .in(PmsTerminal::getId, terminalIds)
                        .in(CollUtil.isNotEmpty(devStatusIds), PmsTerminal::getTerminalState,devStatusIds)
        );
        List<PmsTerminal> records = page.getRecords();
        List<Map<String, String>> info = new ArrayList<>();
        Map<String, String> map;
        for (PmsTerminal terminal : records) {
            map = new LinkedHashMap<>();
            //电能质量监测装置
            map.put("deviceKind", "");
            //运维单位ID
            map.put("maintOrg", terminal.getOperationId());
            //信号输出形式
            map.put("signalInputForm", "");
            //电站类型
            map.put("stationType", "");
            //设备增加方式名称
            map.put("source#Name", "");
            //设备增加方式
            map.put("source", "");
            //电流输出变化
            map.put("currsigInputChanqutity", "");
            //资产单位名称
            map.put("astOrg#Name", "");
            //资产单位
            map.put("astOrg", "");
            //屏柜类型
            map.put("cabinetType", "");
            //时间
            map.put("ctime", "");
            //型号
            map.put("model", "");
            //电站名称
            map.put("station#Name", "");
            //设备所有者
            map.put("equipmentOwner", "");
            //制造商编号
            map.put("manufactureNum", "");
            //Ip地址
            map.put("ipAddress", terminal.getIp());
            //设备编码
            map.put("equipCode", "");
            //子网
            map.put("subnetMask", "");
            //设备ID
            map.put("astId", "");
            //mac地址
            map.put("macAddress", "");
            //信号输出形式名称
            if (mapSignal.containsKey(terminal.getInputType())) {
                DictData dictData = mapSignal.get(terminal.getInputType());
                map.put("signalInputForm#Name", dictData.getName());
            }
            //运维单位名称
            map.put("maintOrg#Name", terminal.getOperationName());
            //名字
            map.put("name", terminal.getName());
            //装置等级
            map.put("deviceLevel", "");
            //工程编号
            map.put("projectNum", "");
            //工程名称
            map.put("projectName", "");
            //操作日期
            map.put("operateDate", "");

            //设备状态
            if (mapDevStatus.containsKey(terminal.getTerminalState())) {
                DictData dictData = mapDevStatus.get(terminal.getTerminalState());
                //设备状态字典
                map.put("deployState", dictData.getValue());
                //设备状态字典名称
                map.put("deployState#Name", dictData.getName());
            }

            //硬盘容量
            map.put("hardDiskCapacity", "");
            //城市
            map.put("city", "");
            //时间同步
            map.put("timeSynchronization", "");
            //资产性质
            map.put("astNature", "");

            //生产厂家
            if (mapManufacture.containsKey(terminal.getManufacture())) {
                DictData dictData = mapManufacture.get(terminal.getManufacture());
                map.put("manufacturer", dictData.getName());
            }

            //设备所属名称
            map.put("astOrgName", "");
            //电压信号输入变化
            map.put("voltsigInputChanqutity", "");
            //运行编号
            map.put("runDevName", "");
            //设备电源电压
            map.put("devPowerVoltage", "");
            //变电站
            map.put("station", "");
            //制造日期
            map.put("manufactureDate", "");
            //资产性质名称
            map.put("astNature#Name", "");
            //端口编号
            map.put("portNum", "");
            //保养组名称
            map.put("maintGroup#Name", "");
            //保养组
            map.put("maintGroup", "");
            //制造商名称
            map.put("manufacturer#Name", "");
            //发现日期
            map.put("detectDate", "");
            //城市名称
            map.put("city#Name", "");
            //变电站类型名称
            map.put("stationType#Name", "");

            //设备级别名称
            map.put("deviceLevel#Name", "");
            //储藏柜
            map.put("cabinet", "");
            //网关
            map.put("gateway", "");
            //电站电压等级名称
            map.put("stationVoltageLevelName", "");
            //终端识别码
            map.put("terminalIdentifyCode", "");
            //终端键
            map.put("terminalKey", "");
            info.add(map);
        }
        PmsPage pmsPage = BeanUtil.copyProperties(page, PmsPage.class);
        pmsPage.setList(info);
        return null;
    }

    @Override
    public PmsPage<Statistical> getMonitorStatisticalDetailList(GwStatisticalParam param) {
        //在线监测点 监测点实收数量大于0，则标识这个监测点就是在线的
        List<RStatIntegrityVO> monitorRealTimeBeZero = new ArrayList<>();
        List<String> lineIds = new ArrayList<>();
        if ("02".equals(param.getFlag())) {
            monitorRealTimeBeZero.addAll(integrityDMapper.getMonitorRealTimeBeZero(null, param.getStartDate(), param.getEndDate(), 0));
            lineIds.addAll(monitorRealTimeBeZero.stream().map(RStatIntegrityVO::getLineIndex).collect(Collectors.toList()));
        }
        List<String> objTypeIds = new ArrayList<>();
        LambdaQueryWrapper<Monitor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(param.getOrgId())) {
            List<String> data = deptFeignClient.getDepSonSelfCodetByCode(param.getOrgId()).getData();
            lambdaQueryWrapper.in(Monitor::getOrgId, data);
        }
         String monitorObjPreName;
        if ("08".equals(param.getStationType())) {
            monitorObjPreName="其他";
            //特殊处理
            List<SysDicTreePO> sysDicTreePOList = dictTreeFeignClient.queryAll().getData();
            List<SysDicTreePO> typicDic = sysDicTreePOList.stream()
                    .filter(item -> Objects.equals(DicTreeEnum.Trans_Sub.getCode(), item.getCode()) ||
                            Objects.equals(DicTreeEnum.Converter.getCode(), item.getCode()) ||
                            Objects.equals(DicTreeEnum.Ele_Railways.getCode(), item.getCode()) ||
                            Objects.equals(DicTreeEnum.Wind_Farms.getCode(), item.getCode()) ||
                            Objects.equals(DicTreeEnum.Power_Station.getCode(), item.getCode()) ||
                            Objects.equals(DicTreeEnum.Smelting_Load.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 {
            //01-变电站,02-换流站,03-电气化铁路,04-风电场,05-光伏电站,06-冶炼负荷,07-重要敏感用户,08-其他
            String code;
            switch (param.getStationType()) {
                case "01":
                    monitorObjPreName=DicTreeEnum.Trans_Sub.getName();
                    code = DicTreeEnum.Trans_Sub.getCode();
                    break;
                case "02":
                    monitorObjPreName=DicTreeEnum.Converter.getName();
                    code = DicTreeEnum.Converter.getCode();
                    break;
                case "03":
                    monitorObjPreName=DicTreeEnum.Ele_Railways.getName();
                    code = DicTreeEnum.Ele_Railways.getCode();
                    break;
                case "04":
                    monitorObjPreName=DicTreeEnum.Wind_Farms.getName();
                    code = DicTreeEnum.Wind_Farms.getCode();
                    break;
                case "05":
                    monitorObjPreName=DicTreeEnum.Power_Station.getName();
                    code = DicTreeEnum.Power_Station.getCode();
                    break;
                case "06":
                    monitorObjPreName=DicTreeEnum.Smelting_Load.getName();
                    code = DicTreeEnum.Smelting_Load.getCode();
                    break;
                case "07":
                    monitorObjPreName=DicTreeEnum.Imp_Users.getName();
                    code = DicTreeEnum.Imp_Users.getCode();
                    break;
                default:
                    return new PmsPage<>(param.getPageNum(), param.getPageSize());
            }
            String id = dictTreeFeignClient.queryByCode(code).getData().getId();
            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);
        lambdaQueryWrapper.in(CollUtil.isNotEmpty(lineIds), Monitor::getId, lineIds);
        Page<Monitor> monitorList = monitorMapper.selectPage(new Page<>(param.getPageNum(), param.getPageSize()), lambdaQueryWrapper);

        if (CollUtil.isNotEmpty(monitorList.getRecords())) {
            List<String> monitorId = monitorList.getRecords().stream().map(Monitor::getId).distinct().collect(Collectors.toList());
            monitorRealTimeBeZero.addAll(integrityDMapper.getMonitorRealTimeBeZero(monitorId, param.getStartDate(), param.getEndDate(), null));
        }
        //线路变电站
        List<String> wireIds = monitorList.getRecords().stream().map(Monitor::getLineId).distinct().collect(Collectors.toList());
        List<String> powerIds = monitorList.getRecords().stream().map(Monitor::getPowerrId).distinct().collect(Collectors.toList());
        List<GeneratrixWire> wiresList = new ArrayList<>();
        List<StatationStat> stationStats = new ArrayList<>();
        if (CollUtil.isNotEmpty(lineIds)) {
            wiresList.addAll(generatrixWireMapper.selectBatchIds(wireIds));
        }
        if (CollUtil.isNotEmpty(powerIds)) {
            stationStats.addAll(statationStatMapper.selectBatchIds(powerIds));
        }
        Map<String, GeneratrixWire> wireMap = wiresList.stream().collect(Collectors
                .toMap(GeneratrixWire::getId, Function.identity()));
        Map<String, StatationStat> powerMap = stationStats.stream().collect(Collectors
                .toMap(StatationStat::getPowerId, 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<String> tractionIds = monitorList.getRecords().stream().map(Monitor::getTractionId).collect(Collectors.toList());
        List<TractionStation> tractionStationList = new ArrayList<>();
        if (CollUtil.isNotEmpty(powerIds)) {
            tractionStationList.addAll(tractionStationService.list(new LambdaQueryWrapper<TractionStation>()
                    .in(TractionStation::getId, tractionIds)));
        }


        Map<String, RStatIntegrityVO> integrityVOMap = monitorRealTimeBeZero.stream().collect(Collectors.toMap(RStatIntegrityVO::getLineIndex, Function.identity()));
        List<Statistical> info = new ArrayList<>();
        Statistical statistical;


        for (Monitor monitor : monitorList.getRecords()) {
            statistical = new Statistical();
            if (integrityVOMap.containsKey(monitor.getId())) {
                RStatIntegrityVO integrity = integrityVOMap.get(monitor.getId());
                statistical.setActualCollectNum(integrity.getRealTime().toString());
                statistical.setExpectCollectNum(integrity.getDueTime().toString());
                statistical.setDataFullRate(integrity.getIntegrityRate().toString());
            } else {
                statistical.setActualCollectNum("0");
                statistical.setExpectCollectNum("0");
                statistical.setDataFullRate("0");
            }
            //母线的电压等级
            if (wireMap.containsKey(monitor.getLineId())) {
                GeneratrixWire generatrixWire = wireMap.get(monitor.getLineId());
                statistical.setBusId(generatrixWire.getMidBusId());
                statistical.setBusName(generatrixWire.getName());
            }
            statistical.setCityId(monitor.getOrgId());
            statistical.setCityName(monitor.getOrgName());
            statistical.setMaintOrg(monitor.getOperationId());
            statistical.setMaintOrgName(monitor.getOperationName());
            statistical.setMonitorId(monitor.getMonitorId());
            statistical.setMonitorName(monitor.getName());
            statistical.setMonitorObjName(monitor.getMonitorObjectName());
            statistical.setOnlineDate(param.getEndDate());
            statistical.setPsrId(monitor.getId());

            statistical.setMonitorObjPre(param.getStationType());
            statistical.setMonitorObjPreName(monitorObjPreName);
//            statistical.setMonitorType();
//            statistical.setMonitorTypeName();
            //变电站
            if (powerMap.containsKey(monitor.getPowerrId())) {
                StatationStat statationStat = powerMap.get(monitor.getPowerrId());
                statistical.setStationId(statationStat.getMidStationId());
                statistical.setStationName(statationStat.getPowerName());
            }
            //电压等级
            if (mapVoltage.containsKey(monitor.getVoltageLevel())) {
                statistical.setVoltageLevel(String.format("%02d", mapVoltage.get(monitor.getVoltageLevel()).getAlgoDescribe()));
                statistical.setVoltageLevelName(mapVoltage.get(monitor.getVoltageLevel()).getName());
            }
            //运行状态
            if (mapLineState.containsKey(monitor.getMonitorState())) {
                statistical.setStatus(mapLineState.get(monitor.getMonitorState()).getValue());
                statistical.setStatusName(mapLineState.get(monitor.getMonitorState()).getName());
            }
            info.add(statistical);
        }
        PmsPage pmsPage = BeanUtil.copyProperties(monitorList, PmsPage.class);
        pmsPage.setList(info);
        return pmsPage;
    }

    private List<String> addmetWorkList(Map<String, List<String>> mapSourceLoad, List<LineDevGetDTO> upToGridList, List<String> line) {
        long total = 0;
        for (String s : mapSourceLoad.keySet()) {
            List<String> value = mapSourceLoad.get(s);
            long monitorCount = upToGridList.stream().filter(item -> value.contains(item.getObjType()) &&
                    Objects.equals(item.getMonitorUploadStatus(), DataStateEnum.ENABLE.getCode())
            ).map(LineDevGetDTO::getPointId).count();
            total += monitorCount;
            line.add(String.valueOf(monitorCount));
        }
        line.add(String.valueOf(total));
        return line;
    }

    private List<String> addSourceLoadList(Map<String, List<String>> mapSourceLoad, List<LineDevGetDTO> upToGridList, List<String> line) {
        long total = 0;
        for (String s : mapSourceLoad.keySet()) {
            List<String> value = mapSourceLoad.get(s);
            long monitorCount = upToGridList.stream().filter(item -> value.contains(item.getObjType()) &&
                    Objects.equals(item.getIsUploadHead(), DataStateEnum.ENABLE.getCode())
            ).map(LineDevGetDTO::getPointId).count();
            total += monitorCount;
            line.add(String.valueOf(monitorCount));
        }
        List<String> sourceLoad = mapSourceLoad.values().stream().flatMap(list -> list.stream()).distinct().collect(Collectors.toList());
        long count = upToGridList.stream().filter(item -> !sourceLoad.contains(item.getObjType()) &&
                Objects.equals(item.getIsUploadHead(), DataStateEnum.ENABLE.getCode())
        ).map(LineDevGetDTO::getPointId).count();
        line.add(String.valueOf(count));
        total += count;
        line.add(String.valueOf(total));
        return line;
    }

    /**
     * @param objType    监测点对象类型大类
     * @param objTypeAll 监测点所有对象类型
     * @return
     */
    private Map<String, List<String>> mapDicIds(List<SysDicTreePO> objType, List<SysDicTreePO> objTypeAll) {
        Map<String, List<String>> mapKey = new LinkedHashMap<>();
        for (SysDicTreePO load : objType) {
            List<String> ids = objTypeAll.stream().filter(item -> item.getPid().equals(load.getId()) ||
                    item.getId().equals(load.getId())
            ).map(SysDicTreePO::getId).collect(Collectors.toList());
            ;
            mapKey.put(load.getCode(), ids);
        }
        return mapKey;
    }

    public List<DeptGetBase> getDeptChildrenByParent(String deptId) {
        List<DeptGetBase> result = new ArrayList<>();
        List<DeptDTO> deptDTOList = deptFeignClient.getDepSonDetailByDeptId(deptId).getData();
        List<DeptDTO> deptList = deptFeignClient.getDeptDescendantIndexes(deptId, Stream.of(0, 1).collect(Collectors.toList())).getData();
        deptDTOList.forEach(it -> {
            DeptGetBase deptGetBase = new DeptGetBase();
            deptGetBase.setUnitId(it.getCode());
            deptGetBase.setUnitName(it.getName());
            List<String> deptChildren = deptList.stream().filter(deptDTO -> deptDTO.getPids().contains(it.getId())).map(DeptDTO::getCode).collect(Collectors.toList());
            deptChildren.add(it.getCode());
            deptGetBase.setUnitChildrenList(deptChildren);
            deptGetBase.setDeptLevel(it.getPids().split(StrUtil.COMMA).length);
            result.add(deptGetBase);
        });
        return result;
    }

}
