package com.njcn.prepare.harmonic.service.mysql.Impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.njcn.device.biz.commApi.CommTerminalGeneralClient;
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.harmonic.pojo.po.day.RStatLimitRateDPO;
import com.njcn.prepare.harmonic.mapper.mysql.day.RStatLimitRateDMapper;
import com.njcn.prepare.harmonic.pojo.param.LineParam;
import com.njcn.prepare.harmonic.pojo.po.SpecialAnalysisIndexOverviewDetailedPO;
import com.njcn.prepare.harmonic.pojo.po.SpecialAnalysisIndexOverviewPO;
import com.njcn.prepare.harmonic.service.mysql.SpecialAnalysisIndexOverviewDetailedPOService;
import com.njcn.prepare.harmonic.service.mysql.SpecialAnalysisIndexOverviewPOService;
import com.njcn.prepare.harmonic.service.mysql.SpecialAnalysisIndexOverviewService;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.pojo.po.Dept;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.DecimalFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * Description:
 * Date: 2023/11/1  15:14【需求编号】
 *
 * @author clam
 * @version V1.0.0
 */
@RequiredArgsConstructor
@Service
public class SpecialAnalysisIndexOverviewServiceImpl implements SpecialAnalysisIndexOverviewService {

    private final CommTerminalGeneralClient commTerminalGeneralClient;
    private final DeptFeignClient deptFeignClient;
    private final RStatLimitRateDMapper rStatLimitRateDMapper;
    private final SpecialAnalysisIndexOverviewPOService specialAnalysisIndexOverviewPOService;
    private final SpecialAnalysisIndexOverviewDetailedPOService specialAnalysisIndexOverviewDetailedPOService;
    @Override
    @Async("asyncExecutor")
    @Transactional(rollbackFor = {Exception.class})
    public void hanlder(LineParam jobParam) {

        List<SpecialAnalysisIndexOverviewPO> specialAnalysisIndexOverviewPOList = new ArrayList<>();
        List<SpecialAnalysisIndexOverviewDetailedPO> specialAnalysisIndexOverviewDetailedPOList = new ArrayList<>();


        Dept data = deptFeignClient.getRootDept().getData();
        DeptGetLineParam deptGetLineParam = new DeptGetLineParam();
        deptGetLineParam.setDeptId(data.getId());
        List<DeptGetChildrenMoreDTO> data1 = commTerminalGeneralClient.deptGetLine(deptGetLineParam).getData();
        Date date = DateUtil.parse(jobParam.getDataDate());

        for (DeptGetChildrenMoreDTO deptGetChildrenMoreDTO : data1) {

            List<LineDevGetDTO> lineBaseList = new ArrayList<>();
            if(CollUtil.isNotEmpty(deptGetChildrenMoreDTO.getLineBaseList())){
                lineBaseList.addAll(deptGetChildrenMoreDTO.getLineBaseList());
            }
            if(CollUtil.isNotEmpty(deptGetChildrenMoreDTO.getPwMonitorIds())){
                lineBaseList.addAll(deptGetChildrenMoreDTO.getPwMonitorIds());
            }

            if (CollUtil.isNotEmpty(lineBaseList)) {
                Map<String, List<LineDevGetDTO>> collect = lineBaseList.stream().collect(Collectors.groupingBy(LineDevGetDTO::getLineTag));



                collect.forEach((k, v) -> {

                    SpecialAnalysisIndexOverviewPO specialAnalysisIndexOverviewPO = new SpecialAnalysisIndexOverviewPO();
                    SpecialAnalysisIndexOverviewDetailedPO specialAnalysisIndexOverviewDetailedPO = new SpecialAnalysisIndexOverviewDetailedPO();

                    specialAnalysisIndexOverviewPO.setOrgNo(deptGetChildrenMoreDTO.getUnitId());
                    specialAnalysisIndexOverviewPO.setDataDate(date);
                    specialAnalysisIndexOverviewPO.setMonitorTag(k);

                    specialAnalysisIndexOverviewDetailedPO.setOrgNo(deptGetChildrenMoreDTO.getUnitId());
                    specialAnalysisIndexOverviewDetailedPO.setDataDate(date);
                    specialAnalysisIndexOverviewDetailedPO.setMonitorTag(k);


                    List<String> collect1 = v.stream().map(LineDevGetDTO::getPointId).collect(Collectors.toList());
                    List<RStatLimitRateDPO> rStatLimitRateMS = rStatLimitRateDMapper.selectList(new LambdaQueryWrapper<RStatLimitRateDPO>()
                            .eq(RStatLimitRateDPO::getPhasicType, "T")
                            .in(RStatLimitRateDPO::getLineId, collect1)
                            .ge(StrUtil.isNotBlank(jobParam.getBeginTime()), RStatLimitRateDPO::getTime, DateUtil.beginOfDay(DateUtil.parse(jobParam.getBeginTime())))
                            .le(StrUtil.isNotBlank(jobParam.getEndTime()), RStatLimitRateDPO::getTime, DateUtil.endOfDay(DateUtil.parse(jobParam.getEndTime()))));
                  if (CollectionUtils.isEmpty(rStatLimitRateMS)){
                      //单位下没数据不补0,0,0的数据
                      return;
                  }


                    Map<String, List<RStatLimitRateDPO>> collect2 = rStatLimitRateMS.stream().collect(Collectors.groupingBy(RStatLimitRateDPO::getLineId));

                    //谐波电流超标监测点数
                    AtomicInteger iCount = new AtomicInteger();
                    //谐波电压含有率超标监测点数
                    AtomicInteger vCount = new AtomicInteger();
                    //电流指标超标点数
                    AtomicInteger iIndexCount = new AtomicInteger();
                    //电压指标超标点数
                    AtomicInteger vIndexCount = new AtomicInteger();


                    //谐波电流超标监测点天数
                    AtomicInteger iDayCount = new AtomicInteger();

                    //谐波电压含有率超标监测点天数
                    AtomicInteger vDayCount = new AtomicInteger();

                    //电流指标超标点天数
                    AtomicInteger iDayIndexCount = new AtomicInteger();

                    //电压指标超标点天数
                    AtomicInteger vDayIndexCount = new AtomicInteger();




                    collect2.forEach((lineId,rStatLimitRateDPOList)->{
                        Map<LocalDate, List<RStatLimitRateDPO>> collect3 = rStatLimitRateDPOList.stream().collect(Collectors.groupingBy(RStatLimitRateDPO::getTime));
                        if(isOverLimit(rStatLimitRateDPOList,1)){
                            iCount.getAndIncrement();
                        }
                        if(isOverLimit(rStatLimitRateDPOList,2)){
                            vCount.getAndIncrement();
                        }
                        if(isOverLimit(rStatLimitRateDPOList,3)){
                            iIndexCount.getAndIncrement();
                        }
                        if(isOverLimit(rStatLimitRateDPOList,4)){
                            vIndexCount.getAndIncrement();
                        }
                        collect3.forEach((day, temp) -> {
                            if(isOverLimit(temp,1)){
                                iDayCount.getAndIncrement();
                            }
                            if(isOverLimit(temp,2)){
                                vDayCount.getAndIncrement();
                            }
                            if(isOverLimit(temp,3)){
                                iDayIndexCount.getAndIncrement();
                            }
                            if(isOverLimit(temp,4)){
                                vDayIndexCount.getAndIncrement();
                            }

                        });
                    });


                    specialAnalysisIndexOverviewPO.setMonitorHarmonicElectricExceedsNum(iCount.get());
                    specialAnalysisIndexOverviewPO.setMonitorHarmonicVoltageContentExceedsNum(vCount.get());
                    specialAnalysisIndexOverviewPO.setElectricIndexExceedsNum(iIndexCount.get());
                    specialAnalysisIndexOverviewPO.setVoltageIndexExceedsNum(vIndexCount.get());

                    specialAnalysisIndexOverviewDetailedPO.setMonitorHarmonicElectricExceedsProportion(
                            this.divideAndKeepTwoDecimalPlaces(iCount.get()*100.0,rStatLimitRateMS.size())
                    );
                    specialAnalysisIndexOverviewDetailedPO.setMonitorHarmonicElectricExceedsAvgDays(
                            this.divideAndKeepTwoDecimalPlaces(iDayCount.get()*1.0,iCount.get())
                    );
                    specialAnalysisIndexOverviewDetailedPO.setMonitorHarmonicVoltageContentExceedsProportion(
                            this.divideAndKeepTwoDecimalPlaces(vCount.get()*100.0,rStatLimitRateMS.size())
                    );
                    specialAnalysisIndexOverviewDetailedPO.setMonitorHarmonicVoltageContentExceedsAvgDays(
                            this.divideAndKeepTwoDecimalPlaces(vDayCount.get()*1.0,vCount.get())
                    );

                    specialAnalysisIndexOverviewDetailedPO.setElectricIndexExceedsProportion(
                            this.divideAndKeepTwoDecimalPlaces(iIndexCount.get()*100.0,rStatLimitRateMS.size())
                    );
                    specialAnalysisIndexOverviewDetailedPO.setElectricIndexExceedsAvgDays(
                            this.divideAndKeepTwoDecimalPlaces(iDayIndexCount.get()*1.0,iIndexCount.get())
                    );
                    specialAnalysisIndexOverviewDetailedPO.setVoltageIndexExceedsProportion(
                            this.divideAndKeepTwoDecimalPlaces(vDayIndexCount.get()*100.0,rStatLimitRateMS.size())
                    );
                    specialAnalysisIndexOverviewDetailedPO.setVoltageIndexExceedsAvgDays(
                            this.divideAndKeepTwoDecimalPlaces(vDayIndexCount.get()*1.0,vIndexCount.get())
                    );

                    specialAnalysisIndexOverviewPOList.add(specialAnalysisIndexOverviewPO);
                    specialAnalysisIndexOverviewDetailedPOList.add(specialAnalysisIndexOverviewDetailedPO);

                });

            }


        }

        if (CollUtil.isNotEmpty(specialAnalysisIndexOverviewPOList)) {
            specialAnalysisIndexOverviewPOService.saveOrUpdateBatchByMultiId(specialAnalysisIndexOverviewPOList, 500);
        }
        if (CollUtil.isNotEmpty(specialAnalysisIndexOverviewDetailedPOList)) {
            specialAnalysisIndexOverviewDetailedPOService.saveOrUpdateBatchByMultiId(specialAnalysisIndexOverviewDetailedPOList, 500);
        }
    }
    /**
    * @Description: isOverLimit
    * @Param:  i代表指标，1,：谐波电流超标 ，2,：谐波电压含有率超标 ，3,：电流指标，4,：电压指标
    * @return: void
    * @Author: clam
    * @Date: 2023/11/2
    */
    private boolean isOverLimit(List<RStatLimitRateDPO> temp, int i) {
        boolean flag = false;
        switch (i) {
            case 1:
                int sum = temp.stream().mapToInt(rStatLimitRateDPO -> {
                    return 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()
                            ;
                }).sum();
                if (sum>0){
                    flag =true;
                }
                break;
            case 2:
                int sum2 = temp.stream().mapToInt(rStatLimitRateDPO -> {
                    return  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()
                            ;
                }).sum();
                if (sum2>0){
                    flag =true;
                }

                break;

            case 3:
                int sum3 = temp.stream().mapToInt(rStatLimitRateDPO -> {
                    return 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() +
                            rStatLimitRateDPO.getINegOvertime()
                            ;
                }).sum();
                if (sum3>0){
                    flag =true;
                }
                break;
            case 4:

                int sum4 = temp.stream().mapToInt(rStatLimitRateDPO -> {
                    return  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.getUharm2Overtime()+
                            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() +
                            rStatLimitRateDPO.getUbalanceOvertime() +
                            rStatLimitRateDPO.getUaberranceOvertime()+
                            rStatLimitRateDPO.getVoltageDevOvertime();
                }).sum();
                if (sum4>0){
                    flag =true;
                }
                break;
            default:
                break;
        }
        return flag;
    }
    /**
    * @Description: divideAndKeepTwoDecimalPlaces
    * @Param:
    * @return: double
    * @Author: clam
    * @Date: 2023/11/2
    */
    public  double divideAndKeepTwoDecimalPlaces(double a, int b) {
        if (b == 0) {
            return 0.00;
        }
        double result =  a / b;
        DecimalFormat df = new DecimalFormat("#.00");
        return Double.parseDouble(df.format(result));
    }

}
