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


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
import com.njcn.device.pms.pojo.po.GeneratrixWire;
import com.njcn.device.pms.pojo.po.Monitor;
import com.njcn.device.pq.pojo.po.RStatIntegrityD;
import com.njcn.harmonic.pojo.po.day.RStatDataVDPO;
import com.njcn.harmonic.pojo.po.day.RStatLimitRateDPO;
import com.njcn.prepare.harmonic.mapper.mysql.area.PmsMonitorPOMapper;
import com.njcn.prepare.harmonic.mapper.mysql.day.RStatDataVDMapper;
import com.njcn.prepare.harmonic.mapper.mysql.day.RStatIntegrityDMapper;
import com.njcn.prepare.harmonic.mapper.mysql.day.RStatLimitRateDMapper;
import com.njcn.prepare.harmonic.mapper.mysql.dim.GeneratrixWireMapper;
import com.njcn.prepare.harmonic.mapper.mysql.upload.RDimBusUpDMapper;
import com.njcn.harmonic.pojo.po.upload.RDimBusUpD;
import com.njcn.prepare.harmonic.service.mysql.upload.IRDimBusUpDService;
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 java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 母线越限详情 服务实现类
 * </p>
 *
 * @author cdf
 * @since 2024-05-09
 */
@Service
@RequiredArgsConstructor
public class RDimBusUpDServiceImpl extends MppServiceImpl<RDimBusUpDMapper, RDimBusUpD> implements IRDimBusUpDService {

    private final RStatIntegrityDMapper rStatIntegrityDMapper;

    private final PmsMonitorPOMapper pmsMonitorPOMapper;

    private final DicDataFeignClient dicDataFeignClient;

    private final RStatLimitRateDMapper rStatLimitRateDMapper;

    private final GeneratrixWireMapper generatrixWireMapper;

    private final RStatDataVDMapper rStatDataVDMapper;


    @Override
    public void handBusDay(String date) {
        TimeInterval timeInterval = new TimeInterval();
        LocalDate localDate = LocalDate.parse(date);

        QueryWrapper<RStatIntegrityD> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("time_id","line_index","real_time/due_time as integrityData","real_time","due_time").
                eq("time_id",localDate);
                //.gt("integrityData",0.95);

        List<RStatIntegrityD> rStatIntegrityDList = rStatIntegrityDMapper.selectList(queryWrapper);
        //Map<String,RStatIntegrityD> rStatIntegrityDMap = rStatIntegrityDList.stream().collect(Collectors.toMap(RStatIntegrityD::getLineIndex, Function.identity()));

        DictData dictData = dicDataFeignClient.getDicDataByCodeAndType(DicDataEnum.RUN.getCode(), DicDataTypeEnum.LINE_STATE.getCode()).getData();
        List<Monitor> monitorList = pmsMonitorPOMapper.selectList(new LambdaQueryWrapper<Monitor>().eq(Monitor::getIsUpToGrid,1).eq(Monitor::getMonitorState,dictData.getId()));

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

        List<String> lineIds = monitorList.stream().map(Monitor::getLineId).distinct().collect(Collectors.toList());
        List<GeneratrixWire> generatrixWireList = generatrixWireMapper.selectList(new LambdaQueryWrapper<GeneratrixWire>().in(GeneratrixWire::getId,lineIds));
        Map<String,GeneratrixWire>  generatrixWireMap = generatrixWireList.stream().collect(Collectors.toMap(GeneratrixWire::getId,Function.identity()));

        List<RStatDataVDPO> rStatDataVDPOList = rStatDataVDMapper.selectList(new LambdaQueryWrapper<RStatDataVDPO>().in(RStatDataVDPO::getLineId,allMonitorIds).eq(RStatDataVDPO::getTime,localDate).eq(RStatDataVDPO::getValueType,"AVG").in(RStatDataVDPO::getPhaseType, Stream.of("A","B","C").collect(Collectors.toList())));
        Map<String,List<RStatDataVDPO>> vMap = rStatDataVDPOList.stream().collect(Collectors.groupingBy(RStatDataVDPO::getLineId));


        List<RStatLimitRateDPO> rStatLimitRateDPOList = rStatLimitRateDMapper.selectList(
                new LambdaQueryWrapper<RStatLimitRateDPO>().in(RStatLimitRateDPO::getLineId,allMonitorIds)
                        .eq(RStatLimitRateDPO::getTime,localDate).in(RStatLimitRateDPO::getPhasicType,Stream.of("A","B","C").collect(Collectors.toList())));
        Map<String,List<RStatLimitRateDPO>> limtMap = rStatLimitRateDPOList.stream().collect(Collectors.groupingBy(RStatLimitRateDPO::getLineId));

        Map<String,List<Monitor>> listMap = monitorList.stream().collect(Collectors.groupingBy(Monitor::getLineId));

        List<RDimBusUpD> poList = new ArrayList<>();
        listMap.forEach((key,val)->{
            List<String> monitorIds = val.stream().map(Monitor::getId).collect(Collectors.toList());
            List<RStatIntegrityD> temIntegrity = rStatIntegrityDList.stream().filter(it->monitorIds.contains(it.getLineIndex())).collect(Collectors.toList());
            if(CollectionUtil.isNotEmpty(temIntegrity)){
               RStatIntegrityD maxR =  temIntegrity.stream().max(Comparator.comparing(RStatIntegrityD::getIntegrityData)).orElse(null);
                assert maxR != null;

                GeneratrixWire generatrixWire = generatrixWireMap.get(key);
                String effectIds = temIntegrity.stream().map(RStatIntegrityD::getLineIndex).collect(Collectors.joining(StrUtil.COMMA));

                Double temAvg= 3.14159;
                if(vMap.containsKey(maxR.getLineIndex())){
                    List<RStatDataVDPO> vList = vMap.get(maxR.getLineIndex());
                    temAvg =  vList.stream().mapToDouble(RStatDataVDPO::getRms).average().orElse(3.14159);
                }
                if(limtMap.containsKey(maxR.getLineIndex())){
                   List<RStatLimitRateDPO> statLimitRateDPOList =  limtMap.get(maxR.getLineIndex());

                    for(RStatLimitRateDPO rStatLimitRateDPO: statLimitRateDPOList){
                        RDimBusUpD rDimBusUpD = new RDimBusUpD();
                        BeanUtil.copyProperties(rStatLimitRateDPO,rDimBusUpD);
                        rDimBusUpD.setBusId(key);
                        rDimBusUpD.setMidBusId(generatrixWire.getMidBusId());
                        rDimBusUpD.setStatisticDate(localDate);
                        rDimBusUpD.setEffectId(maxR.getLineIndex());
                        rDimBusUpD.setEffectIds(effectIds);
                        rDimBusUpD.setVoltageLevel(generatrixWire.getScale());
                        rDimBusUpD.setV(temAvg);
                        poList.add(rDimBusUpD);
                    }
                }

            }
        });
        this.saveOrUpdateBatchByMultiId(poList);

        System.out.println("母线日算法执行时间(S)-----------------------"+timeInterval.intervalSecond());
    }
}
