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


import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
import com.njcn.device.biz.commApi.CommTerminalGeneralClient;
import com.njcn.device.biz.pojo.dto.DeptGetChildrenDTO;
import com.njcn.harmonic.pojo.po.dim.RDimBusGlobalD;
import com.njcn.harmonic.pojo.po.dim.RDimBusbarHarmnicDPO;
import com.njcn.harmonic.pojo.po.dim.RDimStationBaseD;
import com.njcn.prepare.harmonic.mapper.mysql.area.PmsMonitorPOMapper;
import com.njcn.prepare.harmonic.mapper.mysql.day.RStatIntegrityDMapper;
import com.njcn.prepare.harmonic.mapper.mysql.day.RStatLimitTargetDMapper;
import com.njcn.prepare.harmonic.mapper.mysql.dim.GeneratrixWireMapper;
import com.njcn.prepare.harmonic.mapper.mysql.dim.PmsCountLedgerMapper;
import com.njcn.prepare.harmonic.mapper.mysql.dim.RDimBusGlobalDMapper;
import com.njcn.prepare.harmonic.mapper.mysql.line.RMpEventDetailDMapper;
import com.njcn.prepare.harmonic.mapper.mysql.line.ROperatingMonitorDMapper;
import com.njcn.prepare.harmonic.pojo.bo.CalculatedParam;
import com.njcn.prepare.harmonic.service.mysql.dim.IRDimBusGlobalDService;
import com.njcn.prepare.harmonic.service.mysql.dim.IRDimStationBaseDService;
import com.njcn.prepare.harmonic.service.mysql.dim.RDimBusbarHarmnicDPOService;
import com.njcn.user.api.DeptFeignClient;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 母线监测总概览 服务实现类
 * </p>
 *
 * @author hongawen
 * @since 2023-11-14
 */
@Service
@RequiredArgsConstructor
public class RDimBusGlobalDServiceImpl extends MppServiceImpl<RDimBusGlobalDMapper, RDimBusGlobalD> implements IRDimBusGlobalDService {

    private final DeptFeignClient deptFeignClient;

    private final CommTerminalGeneralClient commTerminalGeneralClient;

    private final RStatIntegrityDMapper rStatIntegrityDMapper;

    private final GeneratrixWireMapper generatrixWireMapper;

    private final PmsMonitorPOMapper pmsMonitorPOMapper;

    private final RStatLimitTargetDMapper rStatLimitTargetDMapper;

    private final RMpEventDetailDMapper rMpEventDetailDMapper;

    private final PmsCountLedgerMapper pmsCountLedgerMapper;


    private final ROperatingMonitorDMapper rOperatingMonitorDMapper;

    private final RDimBusbarHarmnicDPOService rDimBusbarHarmnicDPOService;

    private final IRDimStationBaseDService irDimStationBaseDService;


    /**
     * 本算法只有pms使用到,只针对pms主网测点
     *
     * @author cdf
     * @date 2023/11/15
     */
    @Override
    public void globalCalBusBarDay(CalculatedParam<DeptGetChildrenDTO> calculatedParam) {
        List<RDimBusGlobalD> poList = new ArrayList<>();
        LocalDate date = LocalDate.parse(calculatedParam.getDataDate());

        List<DeptGetChildrenDTO> deptList = calculatedParam.getIdList();

        for (DeptGetChildrenDTO dto : deptList) {
            RDimBusGlobalD rDimBusGlobalD = new RDimBusGlobalD();

            List<String> childDept = dto.getDeptChildren();
            LambdaQueryWrapper<RDimBusbarHarmnicDPO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.in(RDimBusbarHarmnicDPO::getOrgId,childDept).eq(RDimBusbarHarmnicDPO::getStatisDate,date);
            List<RDimBusbarHarmnicDPO> rDimBusbarHarmnicDPOList = rDimBusbarHarmnicDPOService.list(lambdaQueryWrapper);
            if(CollUtil.isNotEmpty(rDimBusbarHarmnicDPOList)){
                List<String> goodIds = rDimBusbarHarmnicDPOList.stream().map(RDimBusbarHarmnicDPO::getBusbarId).distinct().collect(Collectors.toList());

                List<RDimBusbarHarmnicDPO> limtList =  rDimBusbarHarmnicDPOList.stream().filter(item->item.getLimitCount()>0).collect(Collectors.toList());
                if(CollUtil.isEmpty(limtList)){
                    rDimBusGlobalD.setLimitRate(0f);
                    rDimBusGlobalD.setLimitAvgRate(0f);
                }else {
                    List<String> busBarIds = limtList.stream().map(RDimBusbarHarmnicDPO::getBusbarId).distinct().collect(Collectors.toList());
                    rDimBusGlobalD.setLimitRate((float)busBarIds.size()/goodIds.size());
                    rDimBusGlobalD.setLimitAvgRate((float)busBarIds.size()/goodIds.size());
                }
            }


            LambdaQueryWrapper<RDimStationBaseD> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(RDimStationBaseD::getOrgId,childDept).eq(RDimStationBaseD::getStatisDate,date);
            List<RDimStationBaseD> rDimStationBaseDList = irDimStationBaseDService.list(queryWrapper);

            if(CollUtil.isNotEmpty(rDimStationBaseDList)){
                long goodStation = rDimStationBaseDList.stream().map(RDimStationBaseD::getStationId).distinct().count();

                List<RDimStationBaseD> limtList =  rDimStationBaseDList.stream().filter(item->item.getLimitCount()>0).collect(Collectors.toList());

                if(CollUtil.isEmpty(limtList)){
                    rDimBusGlobalD.setStationLimitRate(0f);
                    rDimBusGlobalD.setStationLimitAvgRate(0f);
                }else {
                   long limitCount = limtList.stream().map(RDimStationBaseD::getStationId).distinct().count();
                    rDimBusGlobalD.setStationLimitRate((float)limitCount/goodStation);
                    rDimBusGlobalD.setStationLimitAvgRate((float)limitCount/goodStation);
                }
            }

            if(CollUtil.isEmpty(rDimBusbarHarmnicDPOList) && CollUtil.isNotEmpty(rDimStationBaseDList)){
                rDimBusGlobalD.setLimitRate(3.14159f);
                rDimBusGlobalD.setLimitAvgRate(3.14159f);
            }
            if(CollUtil.isNotEmpty(rDimBusbarHarmnicDPOList) && CollUtil.isEmpty(rDimStationBaseDList)){
                rDimBusGlobalD.setStationLimitRate(3.14159f);
                rDimBusGlobalD.setStationLimitAvgRate(3.14159f);
            }
            poList.add(rDimBusGlobalD);

            this.saveOrUpdateBatchByMultiId(poList,100);

         /*   List<String> monitorIds = dto.getLineIds();
            if (CollectionUtil.isNotEmpty(monitorIds)) {
                RDimBusGlobalD rDimBusGlobalD = new RDimBusGlobalD();
                rDimBusGlobalD.setOrgId(dto.getDeptId());
                rDimBusGlobalD.setStatisDate(date);
                //先初步筛选出完整性大于95%的
                LambdaQueryWrapper<RStatIntegrityD> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.in(RStatIntegrityD::getLineIndex, monitorIds).eq(RStatIntegrityD::getTimeId, date);
                List<RStatIntegrityD> integrityDList = rStatIntegrityDMapper.selectList(lambdaQueryWrapper);

                if (CollectionUtil.isEmpty(integrityDList)) {
                    rDimBusGlobalD.setLimitRate(3.14159f);
                    rDimBusGlobalD.setLimitAvgRate(3.14159f);

                    rDimBusGlobalD.setStationLimitRate(3.14159f);
                    rDimBusGlobalD.setStationLimitAvgRate(3.14159f);
                    poList.add(rDimBusGlobalD);
                    continue;
                }

                //不为空还要判断完整性是否大于95%
                integrityDList = integrityDList.stream()
                        .filter(it -> it.getRealTime() / it.getDueTime() >= 0.95f)
                        .collect(Collectors.toList());
                if (CollectionUtil.isEmpty(integrityDList)) {
                    rDimBusGlobalD.setLimitRate(3.14159f);
                    rDimBusGlobalD.setLimitAvgRate(3.14159f);

                    rDimBusGlobalD.setStationLimitRate(3.14159f);
                    rDimBusGlobalD.setStationLimitAvgRate(3.14159f);
                    poList.add(rDimBusGlobalD);
                    continue;
                } else {
                    //有效接入监测点（分母）
                    List<String> goodMonitorIds = integrityDList.stream().map(RStatIntegrityD::getLineIndex).distinct().collect(Collectors.toList());
                    LambdaQueryWrapper<Monitor> monitorLambdaQueryWrapper = new LambdaQueryWrapper<>();
                    monitorLambdaQueryWrapper.select(Monitor::getId, Monitor::getLineId, Monitor::getPowerrId).in(Monitor::getId, goodMonitorIds).eq(Monitor::getStatus, DataStateEnum.ENABLE.getCode());
                    List<Monitor> monitorList = pmsMonitorPOMapper.selectList(monitorLambdaQueryWrapper);
                    List<String> goodLineIds = monitorList.stream().map(Monitor::getLineId).distinct().collect(Collectors.toList());

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


                    LambdaQueryWrapper<RStatLimitTargetDPO> limitWrapper = new LambdaQueryWrapper<>();
                    limitWrapper.in(RStatLimitTargetDPO::getLineId, goodMonitorIds).eq(RStatLimitTargetDPO::getTime, date);
                    List<RStatLimitTargetDPO> rStatLimitRateDPOList = rStatLimitTargetDMapper.selectList(limitWrapper);

                    LambdaQueryWrapper<RMpEventDetailDPO> eventLambda = new LambdaQueryWrapper<>();
                    eventLambda.select(RMpEventDetailDPO::getMeasurementPointId).in(RMpEventDetailDPO::getMeasurementPointId, goodMonitorIds)
                            .eq(RMpEventDetailDPO::getDataDate, date);

                    List<RMpEventDetailDPO> eventList = rMpEventDetailDMapper.selectList(eventLambda);


                    if (CollectionUtil.isEmpty(rStatLimitRateDPOList) && CollectionUtil.isEmpty(eventList)) {
                        rDimBusGlobalD.setLimitRate(3.14159f);
                        rDimBusGlobalD.setLimitAvgRate(3.14159f);

                        rDimBusGlobalD.setStationLimitRate(3.14159f);
                        rDimBusGlobalD.setStationLimitAvgRate(3.14159f);
                        continue;
                    } else {
                        rStatLimitRateDPOList = rStatLimitRateDPOList.stream().filter(item -> item.getAllTime() == 1).collect(Collectors.toList());
                        List<String> dianOneIds = rStatLimitRateDPOList.stream().map(RStatLimitTargetDPO::getLineId).collect(Collectors.toList());
                        eventList = eventList.stream().filter(it -> it.getSagTimes() > 0 || it.getInterruptTimes() > 0 || it.getSwellTimes() > 0).collect(Collectors.toList());
                        List<String> dianTwoIds = eventList.stream().map(RMpEventDetailDPO::getMeasurementPointId).collect(Collectors.toList());

                        Collection<String> union = CollectionUtils.union(dianOneIds, dianTwoIds);
                        List<String> collect = union.stream().distinct().collect(Collectors.toList());

                        if (CollectionUtil.isEmpty(collect)) {
                            rDimBusGlobalD.setLimitRate(0f);
                            rDimBusGlobalD.setLimitAvgRate(0f);

                            rDimBusGlobalD.setStationLimitRate(0f);
                            rDimBusGlobalD.setStationLimitAvgRate(0f);
                        } else {
                            //反推到母线
                            monitorLambdaQueryWrapper.clear();
                            monitorLambdaQueryWrapper.select(Monitor::getId, Monitor::getLineId, Monitor::getPowerrId).in(Monitor::getId, collect).eq(Monitor::getStatus, DataStateEnum.ENABLE.getCode());
                            List<Monitor> temMonitorList = pmsMonitorPOMapper.selectList(monitorLambdaQueryWrapper);
                            List<String> targetLineIds = temMonitorList.stream().map(Monitor::getLineId).distinct().collect(Collectors.toList());

                            float re = (float) targetLineIds.size() / goodLineIds.size() * 100;
                            rDimBusGlobalD.setLimitRate(re);
                            rDimBusGlobalD.setLimitAvgRate(re);

                            //反推电站
                            List<String> targetSubIds = temMonitorList.stream().map(Monitor::getPowerrId).distinct().collect(Collectors.toList());
                            float reStation = (float) targetSubIds.size() / goodStationIds.size() * 100;
                            rDimBusGlobalD.setStationLimitRate(reStation);
                            rDimBusGlobalD.setStationLimitAvgRate(reStation);

                        }
                    }
                }
                poList.add(rDimBusGlobalD);
            }*/
        }
    }








}
