package com.njcn.prepare.harmonic.service.mysql.dim.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
import com.njcn.device.biz.pojo.dto.DeptGetChildrenMoreDTO;
import com.njcn.device.biz.pojo.dto.LineDevGetDTO;
import com.njcn.device.pms.api.StatationStatClient;
import com.njcn.device.pms.pojo.dto.PmsStatationStatInfoDTO;
import com.njcn.device.pms.pojo.param.PmsStatationStatInfoParam;
import com.njcn.device.pms.pojo.po.Monitor;
import com.njcn.event.pojo.po.RMpEventDetailD;
import com.njcn.harmonic.pojo.po.day.RStatLimitRateDPO;
import com.njcn.harmonic.pojo.po.dim.RDimStationHarmnicDPO;
import com.njcn.prepare.harmonic.mapper.mysql.line.PmsMonitorMapper;
import com.njcn.prepare.harmonic.pojo.bo.CalculatedParam;
import com.njcn.prepare.harmonic.pojo.mysql.ROperatingMonitorDPO;
import com.njcn.prepare.harmonic.service.mysql.day.IRStatLimitRateDService;

import com.njcn.prepare.harmonic.service.mysql.dim.RDimStationHarmnicDPOService;
import com.njcn.prepare.harmonic.service.mysql.line.RMpEventDetailDService;
import com.njcn.prepare.harmonic.service.mysql.line.ROperatingMonitorService;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.pojo.po.DictData;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.njcn.prepare.harmonic.mapper.mysql.dim.RDimBusbarHarmnicDPOMapper;
import com.njcn.harmonic.pojo.po.dim.RDimBusbarHarmnicDPO;
import com.njcn.prepare.harmonic.service.mysql.dim.RDimBusbarHarmnicDPOService;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 
 * Description:
 * Date: 2023/11/21  13:45【需求编号】
 *
 * @author clam
 * @version V1.0.0
 */
@Service
@RequiredArgsConstructor
public class RDimBusbarHarmnicDPOServiceImpl extends MppServiceImpl<RDimBusbarHarmnicDPOMapper, RDimBusbarHarmnicDPO> implements RDimBusbarHarmnicDPOService{

    private final DicDataFeignClient dicDataFeignClient;
    private final IRStatLimitRateDService irStatLimitRateDService;
    private final ROperatingMonitorService rOperatingMonitorService;
    private final RMpEventDetailDService rMpEventDetailDService;
    private final RDimStationHarmnicDPOService rMpStationHarmnicDPOService;
    private final StatationStatClient statationStatClient;

    //咨询后直接用Mapper查询，这个算法只用pms补考虑pq，后续不知道要不要改
    private final PmsMonitorMapper pmsMonitorMapper;
    @Override
    public void handleDay(CalculatedParam<DeptGetChildrenMoreDTO> calculatedParam) {
        List<RDimBusbarHarmnicDPO> rDimBusbarHarmnicDPOList = new ArrayList<>();
        //指标对象类型
        List<DictData> indicatorTypeDate = dicDataFeignClient.getDicDataByTypeCode(
                DicDataTypeEnum.STEADY_STATIS.getCode()).getData();
        LocalDate localDate = LocalDateTimeUtil.parseDate(calculatedParam.getDataDate(), DatePattern.NORM_DATE_PATTERN);
        String beginDay = LocalDateTimeUtil.format(LocalDateTimeUtil.beginOfDay(LocalDateTimeUtil.parse(calculatedParam.getDataDate(), DatePattern.NORM_DATE_PATTERN)),DatePattern.NORM_DATETIME_PATTERN);
        String endDay = LocalDateTimeUtil.format(LocalDateTimeUtil.endOfDay(LocalDateTimeUtil.parse(calculatedParam.getDataDate(), DatePattern.NORM_DATE_PATTERN)),DatePattern.NORM_DATETIME_PATTERN);
        /*获取暂态统计指标*/
        List<DictData> eventStatis = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.EVENT_STATIS.getCode()).getData();
        for (DeptGetChildrenMoreDTO deptGetChildrenMoreDTO : calculatedParam.getIdList()) {
            if (!CollectionUtils.isEmpty(deptGetChildrenMoreDTO.getLineBaseList())) {
                List<LineDevGetDTO> lineBaseList = deptGetChildrenMoreDTO.getLineBaseList();
                if (CollectionUtils.isEmpty(lineBaseList)) {
                    continue;
                }
                List<Monitor> monitorList = new ArrayList<>();

                //有效母线数
                Integer effectiveBusbars=0;
                List<String> collect2 = lineBaseList.stream().map(LineDevGetDTO::getPointId).collect(Collectors.toList());
                List<ROperatingMonitorDPO> list = rOperatingMonitorService.lambdaQuery().
                        in(ROperatingMonitorDPO::getMeasurementPointId, collect2).
                        eq(ROperatingMonitorDPO::getDataDate, localDate).
                        ge(ROperatingMonitorDPO::getDataIntegrityRate, 0.95).
                        eq(ROperatingMonitorDPO::getIsUnusual, 1).list();
                if(!CollectionUtils.isEmpty(list)){
                    List<String> collect = list.stream().map(ROperatingMonitorDPO::getMeasurementPointId).distinct().collect(Collectors.toList());
                    monitorList = pmsMonitorMapper.queryEffectiveBusbars(collect);
                    //分组获取最频繁统计监测点
                    Map<String, Optional<Monitor>> collect1 = monitorList.stream().collect(Collectors.groupingBy(Monitor::getLineId,
                            Collectors.minBy(Comparator.comparingInt(Monitor::getStatisticalInterval))));
                    monitorList = collect1.values().stream()
                            .filter(Optional::isPresent)
                            .map(Optional::get)
                            .collect(Collectors.toList());
                }
                if (CollectionUtils.isEmpty(monitorList)) {
                    continue;
                }

                List<String> linids = monitorList.stream().map(Monitor::getId).collect(Collectors.toList());
                List<RStatLimitRateDPO> rStatLimitRateDPOS = irStatLimitRateDService.findList(linids, beginDay, endDay);
                List<RMpEventDetailD> rMpEventDetailDList = rMpEventDetailDService.lambdaQuery().in(RMpEventDetailD::getMeasurementPointId, linids).eq(RMpEventDetailD::getDataDate, localDate).list();
                monitorList.stream().forEach(busbar->{
                    //稳态
                    indicatorTypeDate.stream().forEach(temp->{
                        //总稳态指标排除
                    if (Objects.equals(temp.getCode(), DicDataEnum.TOTAL_INDICATOR.getCode())) {
                        return;
                    }

                        RDimBusbarHarmnicDPO rDimBusbarHarmnicDPO = new RDimBusbarHarmnicDPO();
                        rDimBusbarHarmnicDPO.setOrgId(deptGetChildrenMoreDTO.getUnitId());
                        rDimBusbarHarmnicDPO.setStatisDate(localDate);
                        rDimBusbarHarmnicDPO.setPowerId(busbar.getPowerrId());
                        rDimBusbarHarmnicDPO.setBusbarId(busbar.getLineId());
                        rDimBusbarHarmnicDPO.setTargetType(temp.getId());
                        rDimBusbarHarmnicDPO.setLevel(0);
                        rDimBusbarHarmnicDPO.setMonitorTag(busbar.getMonitorTag());
                        rDimBusbarHarmnicDPO.setVoltageLevel(busbar.getVoltageLevel());
                        Optional<RStatLimitRateDPO> first = rStatLimitRateDPOS.stream().filter(rStatLimitRateDPO -> Objects.equals(rStatLimitRateDPO.getLineId(), busbar.getId())).findFirst();
                        RStatLimitRateDPO rStatLimitRateDPO = new RStatLimitRateDPO();
                        if (first.isPresent()) {
                            rStatLimitRateDPO = first.get();
                        }else {
                            return;
                        }
                        if(Objects.equals(temp.getCode(), DicDataEnum.FLICKER.getCode())){
                            rDimBusbarHarmnicDPO.setStatisCount(rStatLimitRateDPO.getFlickerAllTime());

                        }else {
                            rDimBusbarHarmnicDPO.setStatisCount(rStatLimitRateDPO.getAllTime());

                        }
                        rDimBusbarHarmnicDPO.setLimitCount(overLimitBusbarsCount(temp,rStatLimitRateDPO));
                        rDimBusbarHarmnicDPOList.add(rDimBusbarHarmnicDPO);

                    });
                    //暂态
                    eventStatis.forEach(dictData -> {
                        if (Objects.equals(dictData.getCode(), DicDataEnum.DISTURBANCE.getCode())
                                || Objects.equals(dictData.getCode(), DicDataEnum.OTHER.getCode())
                                || Objects.equals(dictData.getCode(), DicDataEnum.RECORDING_WAVE.getCode())
                                || Objects.equals(dictData.getCode(), DicDataEnum.TOTAL_INDICATORS.getCode())) {
                            return;
                        }
                        RDimBusbarHarmnicDPO rDimBusbarHarmnicDPO = new RDimBusbarHarmnicDPO();
                        rDimBusbarHarmnicDPO.setOrgId(deptGetChildrenMoreDTO.getUnitId());
                        rDimBusbarHarmnicDPO.setStatisDate(localDate);
                        rDimBusbarHarmnicDPO.setTargetType(dictData.getId());
                        rDimBusbarHarmnicDPO.setBusbarId(busbar.getLineId());
                        rDimBusbarHarmnicDPO.setPowerId(busbar.getPowerrId());
                        rDimBusbarHarmnicDPO.setLevel(1);
                        rDimBusbarHarmnicDPO.setMonitorTag(busbar.getMonitorTag());
                        rDimBusbarHarmnicDPO.setVoltageLevel(busbar.getVoltageLevel());
                        Optional<RMpEventDetailD> first = rMpEventDetailDList.stream().filter(rMpEventDetailDPO -> Objects.equals(rMpEventDetailDPO.getMeasurementPointId(), busbar.getId())).findFirst();
                        RMpEventDetailD rMpEventDetailD = new RMpEventDetailD();
                        if (first.isPresent()) {
                            rMpEventDetailD = first.get();
                        }else {
                            return;
                        }

                        rDimBusbarHarmnicDPO.setLimitCount(eventBusbarsCount(dictData, rMpEventDetailD));
                        rDimBusbarHarmnicDPO.setStatisCount(0);
                        rDimBusbarHarmnicDPOList.add(rDimBusbarHarmnicDPO);
                    });

                });

            }
        }
        if (!CollectionUtils.isEmpty(rDimBusbarHarmnicDPOList)) {
            this.saveOrUpdateBatchByMultiId(rDimBusbarHarmnicDPOList, 500);
            Map<String, Map<Integer, Map<String, Map<String, List<RDimBusbarHarmnicDPO>>>>> collect = rDimBusbarHarmnicDPOList.stream().collect(Collectors.groupingBy(RDimBusbarHarmnicDPO::getOrgId,
                    Collectors.groupingBy(RDimBusbarHarmnicDPO::getLevel,
                            Collectors.groupingBy(RDimBusbarHarmnicDPO::getTargetType,
                                    Collectors.groupingBy(RDimBusbarHarmnicDPO::getPowerId)))));
            List<RDimStationHarmnicDPO> rDimStationHarmnicDPOList = new ArrayList<>();
            List<String> powerIdList = rDimBusbarHarmnicDPOList.stream().map(RDimBusbarHarmnicDPO::getPowerId).distinct().collect(Collectors.toList());
            PmsStatationStatInfoParam param = new PmsStatationStatInfoParam();
            param.setPowerIds(powerIdList);
            List<PmsStatationStatInfoDTO> data = statationStatClient.getStatationStatInfo(param).getData();
            collect.forEach((orgId,map)->{
                map.forEach((level,map1)->{
                    map1.forEach((targetType,map2)->{
                        map2.forEach((powerId,map3)->{
                            RDimStationHarmnicDPO rDimStationHarmnicDPO = new RDimStationHarmnicDPO();
                            rDimStationHarmnicDPO.setOrgId(orgId);
                            rDimStationHarmnicDPO.setStatisDate(localDate);
                            rDimStationHarmnicDPO.setTargetType(targetType);
                            rDimStationHarmnicDPO.setStationId(powerId);
                            rDimStationHarmnicDPO.setLevel(level);
                            int sum = map3.stream().map(o->Objects.isNull(o.getStatisCount())?0:o.getStatisCount()).mapToInt(p->p).sum();
                            rDimStationHarmnicDPO.setStatisCount(sum);
                            int limitSum = map3.stream().map(o->Objects.isNull(o.getLimitCount())?0:o.getLimitCount()).mapToInt(p->p).sum();
                            rDimStationHarmnicDPO.setLimitCount(limitSum);
                            rDimStationHarmnicDPO.setVoltageLevel(data.stream().filter(temp->Objects.equals(temp.getPowerId(),powerId)).map(PmsStatationStatInfoDTO::getPowerVoltageLevel).findFirst().orElse("3.14159"));
                            rDimStationHarmnicDPOList.add(rDimStationHarmnicDPO);

                        });
                    });
                });
            });
            if (!CollectionUtils.isEmpty(rDimStationHarmnicDPOList) ) {
                rMpStationHarmnicDPOService.saveOrUpdateBatchByMultiId(rDimStationHarmnicDPOList,500);
            }

        }
    }

    private Integer eventBusbarsCount(DictData dictData, RMpEventDetailD rMpEventDetailD) {
        Integer eventCount =0;
        if (Objects.equals(dictData.getCode(), DicDataEnum.VOLTAGE_DIP.getCode())) {
            eventCount = rMpEventDetailD.getSagTimes();
        } else if ( Objects.equals(dictData.getCode(), DicDataEnum.VOLTAGE_RISE.getCode())) {
            eventCount = rMpEventDetailD.getSwellTimes();

        } else if ( Objects.equals(dictData.getCode(), DicDataEnum.SHORT_INTERRUPTIONS.getCode())) {
            eventCount = rMpEventDetailD.getInterruptTimes();
        }

        return eventCount;
    }


    /**
     * @Description: overLimitBusbarsCount
     * @Param:
     * @return: java.lang.Integer
     * @Author: clam
     * @Date: 2023/11/21
     */
    private Integer overLimitBusbarsCount(DictData temp,RStatLimitRateDPO rStatLimitRateDPO ) {
        Integer overLimiCount =0;

        if (Objects.equals(temp.getCode(), DicDataEnum.VOLTAGE_DEV.getCode())) {
            overLimiCount = rStatLimitRateDPO.getVoltageDevOvertime();
        } else if ( Objects.equals(temp.getCode(), DicDataEnum.FLICKER.getCode())) {
            overLimiCount = rStatLimitRateDPO.getFlickerOvertime();

        } else if ( Objects.equals(temp.getCode(), DicDataEnum.PHASE_VOLTAGE.getCode())) {
            overLimiCount = rStatLimitRateDPO.getUbalanceOvertime();
        } else if (Objects.equals(temp.getCode(), DicDataEnum.THD_V.getCode())){
            overLimiCount = rStatLimitRateDPO.getUaberranceOvertime();
        }else if ( Objects.equals(temp.getCode(), DicDataEnum.HARMONIC_VOLTAGE.getCode())) {
            overLimiCount = Stream.of( rStatLimitRateDPO.getUharm2Overtime(),
                    rStatLimitRateDPO.getUharm3Overtime(),
                    rStatLimitRateDPO.getUharm4Overtime(),
                    rStatLimitRateDPO.getUharm5Overtime(),
                    rStatLimitRateDPO.getUharm6Overtime(),
                    rStatLimitRateDPO.getUharm7Overtime(),
                    rStatLimitRateDPO.getUharm8Overtime(),
                    rStatLimitRateDPO.getUharm9Overtime(),
                    rStatLimitRateDPO.getUharm10Overtime() ,
                    rStatLimitRateDPO.getUharm11Overtime() ,
                    rStatLimitRateDPO.getUharm12Overtime() ,
                    rStatLimitRateDPO.getUharm13Overtime() ,
                    rStatLimitRateDPO.getUharm14Overtime() ,
                    rStatLimitRateDPO.getUharm15Overtime() ,
                    rStatLimitRateDPO.getUharm16Overtime() ,
                    rStatLimitRateDPO.getUharm17Overtime() ,
                    rStatLimitRateDPO.getUharm18Overtime() ,
                    rStatLimitRateDPO.getUharm19Overtime() ,
                    rStatLimitRateDPO.getUharm20Overtime() ,
                    rStatLimitRateDPO.getUharm21Overtime() ,
                    rStatLimitRateDPO.getUharm22Overtime() ,
                    rStatLimitRateDPO.getUharm23Overtime() ,
                    rStatLimitRateDPO.getUharm24Overtime() ,
                    rStatLimitRateDPO.getUharm25Overtime()).max(Integer::compare).get();

        } else if ( Objects.equals(temp.getCode(), DicDataEnum.HARMONIC_CURRENT.getCode())) {
            overLimiCount = Stream.of(rStatLimitRateDPO.getIharm2Overtime(),
                    rStatLimitRateDPO.getIharm3Overtime() ,
                    rStatLimitRateDPO.getIharm4Overtime() ,
                    rStatLimitRateDPO.getIharm5Overtime() ,
                    rStatLimitRateDPO.getIharm6Overtime() ,
                    rStatLimitRateDPO.getIharm7Overtime() ,
                    rStatLimitRateDPO.getIharm8Overtime() ,
                    rStatLimitRateDPO.getIharm9Overtime() ,
                    rStatLimitRateDPO.getIharm10Overtime() ,
                    rStatLimitRateDPO.getIharm11Overtime() ,
                    rStatLimitRateDPO.getIharm12Overtime() ,
                    rStatLimitRateDPO.getIharm13Overtime() ,
                    rStatLimitRateDPO.getIharm14Overtime() ,
                    rStatLimitRateDPO.getIharm15Overtime() ,
                    rStatLimitRateDPO.getIharm16Overtime() ,
                    rStatLimitRateDPO.getIharm17Overtime() ,
                    rStatLimitRateDPO.getIharm18Overtime() ,
                    rStatLimitRateDPO.getIharm19Overtime() ,
                    rStatLimitRateDPO.getIharm20Overtime() ,
                    rStatLimitRateDPO.getIharm21Overtime() ,
                    rStatLimitRateDPO.getIharm22Overtime() ,
                    rStatLimitRateDPO.getIharm23Overtime() ,
                    rStatLimitRateDPO.getIharm24Overtime() ,
                    rStatLimitRateDPO.getIharm25Overtime()).max(Integer::compare).get()
            ;
        } else if (Objects.equals(temp.getCode(), DicDataEnum.INTERHARMONIC_VOLTAGE.getCode())){
            overLimiCount =  Stream.of(rStatLimitRateDPO.getInuharm1Overtime(),
                    rStatLimitRateDPO.getInuharm2Overtime(),
                    rStatLimitRateDPO.getInuharm3Overtime(),
                    rStatLimitRateDPO.getInuharm4Overtime(),
                    rStatLimitRateDPO.getInuharm5Overtime(),
                    rStatLimitRateDPO.getInuharm6Overtime(),
                    rStatLimitRateDPO.getInuharm7Overtime(),
                    rStatLimitRateDPO.getInuharm8Overtime() ,
                    rStatLimitRateDPO.getInuharm9Overtime() ,
                    rStatLimitRateDPO.getInuharm10Overtime() ,
                    rStatLimitRateDPO.getInuharm11Overtime() ,
                    rStatLimitRateDPO.getInuharm12Overtime() ,
                    rStatLimitRateDPO.getInuharm13Overtime() ,
                    rStatLimitRateDPO.getInuharm14Overtime() ,
                    rStatLimitRateDPO.getInuharm15Overtime() ,
                    rStatLimitRateDPO.getInuharm16Overtime() ).max(Integer::compare).get();

        }else if ( Objects.equals(temp.getCode(), DicDataEnum.FREQUENCY_DEV.getCode())) {
            overLimiCount = rStatLimitRateDPO.getFreqDevOvertime();
        } else if (Objects.equals(temp.getCode(), DicDataEnum.NEG_CURRENT.getCode())){
            overLimiCount = rStatLimitRateDPO.getINegOvertime();
        }
        return overLimiCount;
    }
}
