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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.device.biz.pojo.po.Overlimit;
import com.njcn.device.pms.mapper.majornetwork.*;
import com.njcn.device.pms.pojo.dto.MonitorLimitDTO;
import com.njcn.device.pms.pojo.dto.PushMonitorDTO;
import com.njcn.device.pms.pojo.param.PmsMonitorQueryParam;
import com.njcn.device.pms.pojo.po.*;
import com.njcn.device.pms.pojo.vo.gw.OtherUserDto;
import com.njcn.device.pms.service.gwPush.GwMonitorPushService;
import com.njcn.device.pms.service.majornetwork.IMonitorService;
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.pojo.po.DictData;
import com.njcn.system.pojo.po.SysDicTreePO;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.pojo.po.Dept;
import com.njcn.web.enums.GWSendEnum;
import com.njcn.web.factory.PageFactory;
import com.njcn.web.pojo.param.BaseParam;
import com.njcn.web.pojo.param.SendParam;
import com.njcn.web.utils.GwSendUtil;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
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 GwMonitorPushServiceImpl implements GwMonitorPushService {

    private final IMonitorService monitorService;

    private final OverlimitMapper overlimitMapper;

    private final DicDataFeignClient dicDataFeignClient;

    private final DeptFeignClient deptFeignClient;

    private final DictTreeFeignClient dictTreeFeignClient;

    private final StatationStatMapper statationStatMapper;

    private final TerminalMapper terminalMapper;

    private final PmsGeneratrixWireMapper pmsGeneratrixWireMapper;
    private final PmsMidLedgerMapper pmsMidLedgerMapper;


    @Override
    public String pushMonitor(List<String> ids) {

        List<PushMonitorDTO> pushResult = new ArrayList<>();

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

        //监测点对象
        List<DictData> objTagDicList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.MONITORING_LABELS.getCode()).getData();
        Map<String, DictData> objTagMap = objTagDicList.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));

        //监测点状态
        List<DictData> statusDicList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.LINE_STATE.getCode()).getData();
        Map<String, DictData> statusMap = statusDicList.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));

        //电压互感类型
        //List<DictData> tranDicList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.VOLTAGE_TRANSFORMER.getCode()).getData();
        //Map<String, DictData> tranMap = tranDicList.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));

        //中性点接地方式
//        List<DictData> pointDicList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.Neutral_Point.getCode()).getData();
//        Map<String, DictData> pointMap = pointDicList.stream().collect(Collectors.toMap(DictData::getId, Function.identity()));



        LambdaQueryWrapper<Monitor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if(CollUtil.isEmpty(ids)){
            lambdaQueryWrapper
                    .eq(Monitor::getStatus, DataStateEnum.ENABLE.getCode()).eq(Monitor::getIsUpToGrid,1);
        }else {
            lambdaQueryWrapper.in(Monitor::getId, ids).eq(Monitor::getStatus, DataStateEnum.ENABLE.getCode()).eq(Monitor::getIsUpToGrid,1);
        }
        List<Monitor> monitorList = monitorService.list(lambdaQueryWrapper);
        if(CollUtil.isEmpty(monitorList)){
            throw new BusinessException("未查询到有效监测点！");
        }



        List<String> stationIds = monitorList.stream().map(Monitor::getPowerrId).distinct().collect(Collectors.toList());
        List<String> terminalIds = monitorList.stream().map(Monitor::getTerminalId).distinct().collect(Collectors.toList());
        List<String> busIds = monitorList.stream().map(Monitor::getLineId).distinct().collect(Collectors.toList());

        List<StatationStat> statationStatList = statationStatMapper.selectList(new LambdaQueryWrapper<StatationStat>().in(StatationStat::getPowerId,stationIds));
        Map<String,StatationStat> mapStation = statationStatList.stream().collect(Collectors.toMap(StatationStat::getPowerId,Function.identity()));

        List<PmsTerminal> pmsTerminalList = terminalMapper.selectList(new LambdaQueryWrapper<PmsTerminal>().in(PmsTerminal::getId,terminalIds));
        List<PmsTerminal> newPmsTerminalList = pmsTerminalList.stream().filter(item->Objects.isNull(item.getTerminalCode())).collect(Collectors.toList());

        if(CollUtil.isNotEmpty(newPmsTerminalList)){
            throw new BusinessException("存在关联的监测终端为空的监测点，请排查");
        }

        List<GeneratrixWire> GeneratrixWireList = pmsGeneratrixWireMapper.selectList(new LambdaQueryWrapper<GeneratrixWire>().in(GeneratrixWire::getId,busIds));
        List<GeneratrixWire> newGeneratrixWireList = GeneratrixWireList.stream().filter(item->Objects.isNull(item.getMidBusId())).collect(Collectors.toList());
        if(CollUtil.isNotEmpty(newGeneratrixWireList)){
            throw new BusinessException("存在关联母线为空的监测点，请排查");
        }

        Map<String,PmsTerminal> mapTerminal = pmsTerminalList.stream().collect(Collectors.toMap(PmsTerminal::getId,Function.identity()));
        Map<String,GeneratrixWire> mapBus = GeneratrixWireList.stream().collect(Collectors.toMap(GeneratrixWire::getId,Function.identity()));


        //获取母线中台信息
        List<PmsMidLedger> pmsMidLedgers = pmsMidLedgerMapper.selectList(new LambdaQueryWrapper<PmsMidLedger>()
                .in(PmsMidLedger::getId, GeneratrixWireList.stream().map(GeneratrixWire::getMidBusId).distinct().collect(Collectors.toList()))
        );
        Map<String,PmsMidLedger> mapMidLedger = pmsMidLedgers.stream().collect(Collectors.toMap(PmsMidLedger::getId,Function.identity()));

        //单位处理
        List<Dept> deptList = deptFeignClient.getAllDept().getData();
        Map<String,Dept> deptMap = deptList.stream().collect(Collectors.toMap(Dept::getCode,Function.identity()));
        Map<String,Dept> deptIdMap = deptList.stream().collect(Collectors.toMap(Dept::getId,Function.identity()));


        for (Monitor item : monitorList) {
            PushMonitorDTO pushMonitorDTO = new PushMonitorDTO();
            pushMonitorDTO.setId(item.getId());
            pushMonitorDTO.setMonitorId(item.getMonitorId());
            pushMonitorDTO.setMonitorName(item.getName());
            pushMonitorDTO.setTerminalCode(item.getTerminalId());
            pushMonitorDTO.setCityId(deptIdMap.get(deptMap.get(item.getOrgId()).getPid()).getCode());
            pushMonitorDTO.setIsMajorNet("1");

            pushMonitorDTO.setProvinceId("13B9B47F1E483324E05338297A0A0595");
            pushMonitorDTO.setProvinceName("国网河北电力有限公司");

            if(mapStation.containsKey(item.getPowerrId())) {
                pushMonitorDTO.setSubstationId(mapStation.get(item.getPowerrId()).getMidStationId());
                pushMonitorDTO.setSubstationName(mapStation.get(item.getPowerrId()).getPowerName());
            }

            //终端
            pushMonitorDTO.setTerminalCode(mapTerminal.get(item.getTerminalId()).getTerminalCode());

            //母线
            pushMonitorDTO.setBusId(mapBus.get(item.getLineId()).getMidBusId());
            //母线名称
            if (mapMidLedger.containsKey(mapBus.get(item.getLineId()).getMidBusId())) {
                pushMonitorDTO.setBusName(mapMidLedger.get(mapBus.get(item.getLineId()).getMidBusId()).getName());
            }


            if (voltageMap.containsKey(item.getVoltageLevel())) {
                pushMonitorDTO.setVoltageLevel(String.format("%02d", voltageMap.get(item.getVoltageLevel()).getAlgoDescribe()));
            }


            //对象类型
           SysDicTreePO sysDicTreePO = dictTreeFeignClient.queryById(item.getObjType()).getData();
            if(sysDicTreePO.getPid().equals("0")){
                pushMonitorDTO.setObjectType(sysDicTreePO.getCode());
                pushMonitorDTO.setObjTypePre(sysDicTreePO.getCode());
            }else {
                pushMonitorDTO.setObjectType(sysDicTreePO.getCode());
                SysDicTreePO sysDicTreeParent = dictTreeFeignClient.queryById(sysDicTreePO.getPid()).getData();
                pushMonitorDTO.setObjTypePre(sysDicTreeParent.getCode());
            }

            pushMonitorDTO.setObjTypePrePre(item.getPowerFlag());


            if (statusMap.containsKey(item.getMonitorState())) {
                pushMonitorDTO.setStatus(statusMap.get(item.getMonitorState()).getValue());
            }


            if (Objects.nonNull(item.getMinShortCircuitCapacity())) {
                pushMonitorDTO.setMinShortCapacity(BigDecimal.valueOf(item.getMinShortCircuitCapacity()));
            }
            if (Objects.nonNull(item.getStandShortCapacity())) {
                pushMonitorDTO.setBmShortCapacity(BigDecimal.valueOf(item.getStandShortCapacity()));
            }
            if (Objects.nonNull(item.getPowerSupplyEqCapacity())) {
                pushMonitorDTO.setSupplyEquipCapacity(BigDecimal.valueOf(item.getPowerSupplyEqCapacity()));
            }
            if (Objects.nonNull(item.getUserAgreementCapacity())) {
                pushMonitorDTO.setUserProtocolCapacity(BigDecimal.valueOf(item.getUserAgreementCapacity()));
            }

            if (Objects.nonNull(item.getMonitorObjectName())) {
                pushMonitorDTO.setCustomName(item.getMonitorObjectName());
            }



            pushMonitorDTO.setUpdateTime(item.getUpdateTime());


            if (StrUtil.isNotBlank(item.getOrgName())) {
                pushMonitorDTO.setMaintOrg(item.getOrgId());
            }
            if (Objects.nonNull(item.getStatisticalInterval())) {
                pushMonitorDTO.setStatisticalInterval(item.getStatisticalInterval().toString());
            }

            pushMonitorDTO.setMonitorTag(objTagMap.get(item.getMonitorTag()).getValue());

          /*  if (StrUtil.isNotBlank(item.getMonitorObjectId())) {
                pushMonitorDTO.setMonitorObjId(item.getMonitorObjectId());
            }*/
            pushResult.add(pushMonitorDTO);
        }







        if(pushResult.size()>100){
            List<List<PushMonitorDTO>> pushMonitorDTOList = ListUtil.split(pushResult,100);

            int countAll = 0;
            for(List<PushMonitorDTO> list : pushMonitorDTOList){
                SendParam sendParam = new SendParam();
                sendParam.setStats(list);
                Map<String, String> sendRes = GwSendUtil.send(sendParam, GWSendEnum.MONITOR);
                List<String> mIds = list.stream().map(PushMonitorDTO::getId).distinct().collect(Collectors.toList());

                if (sendRes.containsKey("succeed")) {
                    String succeed = sendRes.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(1, mIds);
                        String result = mapData.get("result").toString();
                        Map mapCount = JSON.parseObject(result, Map.class);
                        int count = Integer.parseInt(mapCount.get("count").toString());
                        countAll+=count;
                    } else {
                        String errors = mapData.get("errors").toString();
                        throw new BusinessException("操作失败:" + status + "_" + errors);
                    }
                } else {
                    throw new BusinessException("当前时间段国网上送请求过多，请稍后再试");
                }
            }
            return "操作成功:成功数据" + countAll + "条";
        }else {
            SendParam sendParam = new SendParam();
            sendParam.setStats(pushResult);
            Map<String, String> sendRes = GwSendUtil.send(sendParam, GWSendEnum.MONITOR);
            List<String> mIds = monitorList.stream().map(Monitor::getId).distinct().collect(Collectors.toList());
            String msg = returnInformation(1, mIds, sendRes);
            return msg;
        }


    }



    @Override
    public String pushMonitorOverLimit(List<String> ids) {
       /* if (ids.size() > 100) {
            throw new BusinessException("一次最多上送100条数据");
        }*/

        List<MonitorLimitDTO> pushResult = new ArrayList<>();

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


        LambdaQueryWrapper<Monitor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if(CollUtil.isEmpty(ids)){
            lambdaQueryWrapper
                    .eq(Monitor::getStatus, DataStateEnum.ENABLE.getCode()).eq(Monitor::getIsUpToGrid,1);
        }else {
            lambdaQueryWrapper.in(Monitor::getId, ids).eq(Monitor::getIsUpToGrid,1).eq(Monitor::getStatus, DataStateEnum.ENABLE.getCode());
        }
        List<Monitor> monitorList = monitorService.list(lambdaQueryWrapper);

        if(CollUtil.isEmpty(monitorList)){
            throw new BusinessException("未查询到有效监测点！");
        }



        List<String> monitorIds = monitorList.stream().map(Monitor::getId).distinct().collect(Collectors.toList());


        LambdaQueryWrapper<Overlimit> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Overlimit::getId, monitorIds);
        List<Overlimit> overlimitList = overlimitMapper.selectList(queryWrapper);
        Map<String, Overlimit> map = overlimitList.stream().collect(Collectors.toMap(Overlimit::getId, Function.identity()));

        if (CollUtil.isNotEmpty(monitorList)) {
            for (Monitor monitor : monitorList) {
                MonitorLimitDTO monitorLimitDTO = new MonitorLimitDTO();
                monitorLimitDTO.setId(monitor.getId());
                //monitorLimitDTO.setOcDate(new Date());
                monitorLimitDTO.setMonitorId(monitor.getId());

                monitorLimitDTO.setPt((int) (monitor.getPt1() /monitor.getPt2()));
                monitorLimitDTO.setCt((int) (monitor.getCt1() /monitor.getCt2()));

                if (voltageMap.containsKey(monitor.getVoltageLevel())) {
                    monitorLimitDTO.setVoltage(String.format("%02d", voltageMap.get(monitor.getVoltageLevel()).getAlgoDescribe()));
                }

                Overlimit overlimit = map.get(monitor.getId());

                monitorLimitDTO.setVoldelimiteUp(BigDecimal.valueOf(monitor.getVoltageDeviationUpperLimit()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setVoldelimiteLow(BigDecimal.valueOf(monitor.getVoltageDeviationLowerLimit()).setScale(3, RoundingMode.HALF_UP));



                monitorLimitDTO.setPltLimit(BigDecimal.valueOf(overlimit.getFlicker()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setRatedeLimiteUp(BigDecimal.valueOf(overlimit.getFreqDev()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setRatedeLimiteDown(BigDecimal.valueOf(-overlimit.getFreqDev()).setScale(3, RoundingMode.HALF_UP));

                monitorLimitDTO.setVthdLimit(BigDecimal.valueOf(overlimit.getUaberrance()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setFlucLimit(BigDecimal.valueOf(overlimit.getVoltageFluctuation()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setDeltaLimit(BigDecimal.valueOf(overlimit.getVoltageDev()).setScale(3, RoundingMode.HALF_UP));

                monitorLimitDTO.setVunbanLimit(BigDecimal.valueOf(overlimit.getUbalance()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setOddHamVPerate(BigDecimal.valueOf(overlimit.getUharm3()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setEveHamVPerate(BigDecimal.valueOf(overlimit.getUharm2()).setScale(3, RoundingMode.HALF_UP));

                monitorLimitDTO.setI2Limit(BigDecimal.valueOf(overlimit.getIharm2()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI3Limit(BigDecimal.valueOf(overlimit.getIharm3()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI4Limit(BigDecimal.valueOf(overlimit.getIharm4()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI5Limit(BigDecimal.valueOf(overlimit.getIharm5()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI6Limit(BigDecimal.valueOf(overlimit.getIharm6()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI7Limit(BigDecimal.valueOf(overlimit.getIharm7()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI8Limit(BigDecimal.valueOf(overlimit.getIharm8()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI9Limit(BigDecimal.valueOf(overlimit.getIharm9()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI10Limit(BigDecimal.valueOf(overlimit.getIharm10()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI11Limit(BigDecimal.valueOf(overlimit.getIharm11()).setScale(3, RoundingMode.HALF_UP));

                monitorLimitDTO.setI12Limit(BigDecimal.valueOf(overlimit.getIharm12()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI13Limit(BigDecimal.valueOf(overlimit.getIharm13()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI14Limit(BigDecimal.valueOf(overlimit.getIharm14()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI15Limit(BigDecimal.valueOf(overlimit.getIharm15()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI16Limit(BigDecimal.valueOf(overlimit.getIharm16()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI17Limit(BigDecimal.valueOf(overlimit.getIharm17()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI18Limit(BigDecimal.valueOf(overlimit.getIharm18()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI19Limit(BigDecimal.valueOf(overlimit.getIharm19()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI20Limit(BigDecimal.valueOf(overlimit.getIharm20()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI21Limit(BigDecimal.valueOf(overlimit.getIharm21()).setScale(3, RoundingMode.HALF_UP));

                monitorLimitDTO.setI22Limit(BigDecimal.valueOf(overlimit.getIharm22()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI23Limit(BigDecimal.valueOf(overlimit.getIharm23()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI24Limit(BigDecimal.valueOf(overlimit.getIharm24()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI25Limit(BigDecimal.valueOf(overlimit.getIharm25()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI26Limit(BigDecimal.valueOf(overlimit.getIharm26()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI27Limit(BigDecimal.valueOf(overlimit.getIharm27()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI28Limit(BigDecimal.valueOf(overlimit.getIharm28()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI29Limit(BigDecimal.valueOf(overlimit.getIharm29()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI30Limit(BigDecimal.valueOf(overlimit.getIharm30()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI31Limit(BigDecimal.valueOf(overlimit.getIharm31()).setScale(3, RoundingMode.HALF_UP));

                monitorLimitDTO.setI32Limit(BigDecimal.valueOf(overlimit.getIharm32()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI33Limit(BigDecimal.valueOf(overlimit.getIharm33()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI34Limit(BigDecimal.valueOf(overlimit.getIharm34()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI35Limit(BigDecimal.valueOf(overlimit.getIharm35()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI36Limit(BigDecimal.valueOf(overlimit.getIharm36()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI37Limit(BigDecimal.valueOf(overlimit.getIharm37()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI38Limit(BigDecimal.valueOf(overlimit.getIharm38()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI39Limit(BigDecimal.valueOf(overlimit.getIharm39()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI40Limit(BigDecimal.valueOf(overlimit.getIharm40()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI41Limit(BigDecimal.valueOf(overlimit.getIharm41()).setScale(3, RoundingMode.HALF_UP));

                monitorLimitDTO.setI42Limit(BigDecimal.valueOf(overlimit.getIharm42()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI43Limit(BigDecimal.valueOf(overlimit.getIharm43()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI44Limit(BigDecimal.valueOf(overlimit.getIharm44()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI45Limit(BigDecimal.valueOf(overlimit.getIharm45()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI46Limit(BigDecimal.valueOf(overlimit.getIharm46()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI47Limit(BigDecimal.valueOf(overlimit.getIharm47()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI48Limit(BigDecimal.valueOf(overlimit.getIharm48()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI49Limit(BigDecimal.valueOf(overlimit.getIharm49()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI50Limit(BigDecimal.valueOf(overlimit.getIharm50()).setScale(3, RoundingMode.HALF_UP));

                monitorLimitDTO.setHarmonicVoltageLimit2(BigDecimal.valueOf(overlimit.getInuharm1()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setHarmonicVoltageLimit3to16(BigDecimal.valueOf(overlimit.getInuharm3()).setScale(3, RoundingMode.HALF_UP));


                pushResult.add(monitorLimitDTO);
            }

            if(pushResult.size()>100){
                List<List<MonitorLimitDTO>> pushMonitorDTOList = ListUtil.split(pushResult,100);

                int countAll = 0;
                for(List<MonitorLimitDTO> list : pushMonitorDTOList){
                    SendParam sendParam = new SendParam();
                    sendParam.setStats(list);
                    Map<String, String> sendRes = GwSendUtil.send(sendParam, GWSendEnum.LIMIT_CREATE);
                    List<String> mIds = list.stream().map(MonitorLimitDTO::getId).distinct().collect(Collectors.toList());

                    if (sendRes.containsKey("succeed")) {
                        String succeed = sendRes.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(2, mIds);
                            String result = mapData.get("result").toString();
                            Map mapCount = JSON.parseObject(result, Map.class);
                            int count = Integer.parseInt(mapCount.get("count").toString());
                            countAll+=count;
                        } else {
                            String errors = mapData.get("errors").toString();
                            throw new BusinessException("操作失败:" + status + "_" + errors);
                        }
                    } else {
                        throw new BusinessException("当前时间段国网上送请求过多，请稍后再试");
                    }
                }
                return "操作成功:成功数据" + countAll + "条";
            }else {
                SendParam sendParam = new SendParam();
                sendParam.setStats(pushResult);
                Map<String, String> sendRes = GwSendUtil.send(sendParam, GWSendEnum.LIMIT_CREATE);
                List<String> mIds = monitorList.stream().map(Monitor::getId).distinct().collect(Collectors.toList());
                String msg = returnInformation(2, mIds, sendRes);
                return msg;
            }


        } else {
            throw new BusinessException("暂无监测点信息");
        }

    }

    @Override
    public Page<MonitorLimitDTO> queryMonitorOverLimit(PmsMonitorQueryParam baseParam) {
        Page<MonitorLimitDTO> pageResult = new Page<>(PageFactory.getPageNum(baseParam), PageFactory.getPageSize(baseParam));
        LambdaQueryWrapper<Monitor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StrUtil.isNotBlank(baseParam.getMonitorState()),Monitor::getMonitorState,baseParam.getMonitorState())
                        .eq(Objects.nonNull(baseParam.getIsUpToGrid()),Monitor::getIsUpToGrid,baseParam.getIsUpToGrid())
                .and(StrUtil.isNotBlank(baseParam.getSearchValue()), i -> i.like(Monitor::getName, baseParam.getSearchValue())
                .or()
                .like(Monitor::getId, baseParam.getSearchValue())
                .or()
                .like(Monitor::getPowerrName, baseParam.getSearchValue())
                .or()
                .like(Monitor::getOrgName, baseParam.getSearchValue()));
        lambdaQueryWrapper.orderByAsc(Monitor::getOrgName);
        Page<Monitor> page = monitorService.page(new Page<>(PageFactory.getPageNum(baseParam), PageFactory.getPageSize(baseParam)), lambdaQueryWrapper);
        pageResult.setTotal(page.getTotal());
        List<Monitor> pageTemList = page.getRecords();
        if (CollUtil.isNotEmpty(pageTemList)) {
            List<String> ids = pageTemList.stream().map(Monitor::getId).distinct().collect(Collectors.toList());
            LambdaQueryWrapper<Overlimit> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(Overlimit::getId, ids);
            List<Overlimit> overlimitList = overlimitMapper.selectList(queryWrapper);
            Map<String, Overlimit> map = overlimitList.stream().collect(Collectors.toMap(Overlimit::getId, Function.identity()));

            List<MonitorLimitDTO> monitorLimitDTOList = new ArrayList<>();
            for (Monitor monitor : pageTemList) {
                MonitorLimitDTO monitorLimitDTO = new MonitorLimitDTO();
                monitorLimitDTO.setId(monitor.getId());
                monitorLimitDTO.setMonitorName(monitor.getName());
                monitorLimitDTO.setOrgId(monitor.getOrgId());
                monitorLimitDTO.setOrgName(monitor.getOrgName());
                //monitorLimitDTO.setOcDate(new Date());

                monitorLimitDTO.setPt((int) (monitor.getPt1() /monitor.getPt2()));
                monitorLimitDTO.setCt((int) (monitor.getCt1() /monitor.getCt2()));
                monitorLimitDTO.setMonitorId(monitor.getMonitorId());

                monitorLimitDTO.setVoltage(monitor.getVoltageLevel());
                monitorLimitDTO.setMonitorUploadStatus(monitor.getMonitorOverlimitStatus());


                monitorLimitDTO.setVoldelimiteUp(BigDecimal.valueOf(monitor.getVoltageDeviationUpperLimit()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setVoldelimiteLow(BigDecimal.valueOf(monitor.getVoltageDeviationLowerLimit()).setScale(3, RoundingMode.HALF_UP));

                Overlimit overlimit = map.get(monitor.getId());

                monitorLimitDTO.setPltLimit(BigDecimal.valueOf(overlimit.getFlicker()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setRatedeLimiteUp(BigDecimal.valueOf(overlimit.getFreqDev()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setRatedeLimiteDown(BigDecimal.valueOf(-overlimit.getFreqDev()).setScale(3, RoundingMode.HALF_UP));

                monitorLimitDTO.setVthdLimit(BigDecimal.valueOf(overlimit.getUaberrance()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setFlucLimit(BigDecimal.valueOf(overlimit.getVoltageFluctuation()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setDeltaLimit(BigDecimal.valueOf(overlimit.getVoltageDev()).setScale(3, RoundingMode.HALF_UP));

                monitorLimitDTO.setVunbanLimit(BigDecimal.valueOf(overlimit.getUbalance()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setOddHamVPerate(BigDecimal.valueOf(overlimit.getUharm3()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setEveHamVPerate(BigDecimal.valueOf(overlimit.getUharm2()).setScale(3, RoundingMode.HALF_UP));

                monitorLimitDTO.setI2Limit(BigDecimal.valueOf(overlimit.getIharm2()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI3Limit(BigDecimal.valueOf(overlimit.getIharm3()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI4Limit(BigDecimal.valueOf(overlimit.getIharm4()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI5Limit(BigDecimal.valueOf(overlimit.getIharm5()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI6Limit(BigDecimal.valueOf(overlimit.getIharm6()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI7Limit(BigDecimal.valueOf(overlimit.getIharm7()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI8Limit(BigDecimal.valueOf(overlimit.getIharm8()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI9Limit(BigDecimal.valueOf(overlimit.getIharm9()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI10Limit(BigDecimal.valueOf(overlimit.getIharm10()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI11Limit(BigDecimal.valueOf(overlimit.getIharm11()).setScale(3, RoundingMode.HALF_UP));

                monitorLimitDTO.setI12Limit(BigDecimal.valueOf(overlimit.getIharm12()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI13Limit(BigDecimal.valueOf(overlimit.getIharm13()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI14Limit(BigDecimal.valueOf(overlimit.getIharm14()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI15Limit(BigDecimal.valueOf(overlimit.getIharm15()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI16Limit(BigDecimal.valueOf(overlimit.getIharm16()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI17Limit(BigDecimal.valueOf(overlimit.getIharm17()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI18Limit(BigDecimal.valueOf(overlimit.getIharm18()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI19Limit(BigDecimal.valueOf(overlimit.getIharm19()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI20Limit(BigDecimal.valueOf(overlimit.getIharm20()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI21Limit(BigDecimal.valueOf(overlimit.getIharm21()).setScale(3, RoundingMode.HALF_UP));

                monitorLimitDTO.setI22Limit(BigDecimal.valueOf(overlimit.getIharm22()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI23Limit(BigDecimal.valueOf(overlimit.getIharm23()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI24Limit(BigDecimal.valueOf(overlimit.getIharm24()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI25Limit(BigDecimal.valueOf(overlimit.getIharm25()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI26Limit(BigDecimal.valueOf(overlimit.getIharm26()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI27Limit(BigDecimal.valueOf(overlimit.getIharm27()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI28Limit(BigDecimal.valueOf(overlimit.getIharm28()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI29Limit(BigDecimal.valueOf(overlimit.getIharm29()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI30Limit(BigDecimal.valueOf(overlimit.getIharm30()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI31Limit(BigDecimal.valueOf(overlimit.getIharm31()).setScale(3, RoundingMode.HALF_UP));

                monitorLimitDTO.setI32Limit(BigDecimal.valueOf(overlimit.getIharm32()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI33Limit(BigDecimal.valueOf(overlimit.getIharm33()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI34Limit(BigDecimal.valueOf(overlimit.getIharm34()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI35Limit(BigDecimal.valueOf(overlimit.getIharm35()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI36Limit(BigDecimal.valueOf(overlimit.getIharm36()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI37Limit(BigDecimal.valueOf(overlimit.getIharm37()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI38Limit(BigDecimal.valueOf(overlimit.getIharm38()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI39Limit(BigDecimal.valueOf(overlimit.getIharm39()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI40Limit(BigDecimal.valueOf(overlimit.getIharm40()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI41Limit(BigDecimal.valueOf(overlimit.getIharm41()).setScale(3, RoundingMode.HALF_UP));

                monitorLimitDTO.setI42Limit(BigDecimal.valueOf(overlimit.getIharm42()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI43Limit(BigDecimal.valueOf(overlimit.getIharm43()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI44Limit(BigDecimal.valueOf(overlimit.getIharm44()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI45Limit(BigDecimal.valueOf(overlimit.getIharm45()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI46Limit(BigDecimal.valueOf(overlimit.getIharm46()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI47Limit(BigDecimal.valueOf(overlimit.getIharm47()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI48Limit(BigDecimal.valueOf(overlimit.getIharm48()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI49Limit(BigDecimal.valueOf(overlimit.getIharm49()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setI50Limit(BigDecimal.valueOf(overlimit.getIharm50()).setScale(3, RoundingMode.HALF_UP));

                monitorLimitDTO.setHarmonicVoltageLimit2(BigDecimal.valueOf(overlimit.getInuharm1()).setScale(3, RoundingMode.HALF_UP));
                monitorLimitDTO.setHarmonicVoltageLimit3to16(BigDecimal.valueOf(overlimit.getInuharm3()).setScale(3, RoundingMode.HALF_UP));


                monitorLimitDTOList.add(monitorLimitDTO);
            }

            pageResult.setRecords(monitorLimitDTOList);
        }
        return pageResult;
    }


    /**
     * 国网上送返回信息
     *
     * @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::getMonitorUploadStatus, 1)
                        .in(Monitor::getId, ids)
                );
                break;
            case 2:
                monitorService.update(new LambdaUpdateWrapper<Monitor>()
                        .set(Monitor::getMonitorOverlimitStatus, 1)
                        .in(Monitor::getId, ids)
                );
                break;
            default:
                break;
        }
    }
}
