package com.njcn.harmonic.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.config.GeneralInfo;
import com.njcn.device.api.GeneralDeviceInfoClient;
import com.njcn.device.api.LineFeignClient;
import com.njcn.device.pojo.dto.GeneralDeviceDTO;
import com.njcn.device.pojo.dto.OverLimitLineDTO;
import com.njcn.device.pojo.dto.PollutionParamDTO;
import com.njcn.device.pojo.dto.WarningSubstationDTO;
import com.njcn.harmonic.constant.Param;
import com.njcn.harmonic.pojo.dto.excel.area.AreaExcel;
import com.njcn.harmonic.pojo.po.EventDetail;
import com.njcn.harmonic.pojo.po.LimitRate;
import com.njcn.harmonic.pojo.po.LimitTarget;
import com.njcn.harmonic.pojo.vo.MonitorOverLimitVO;
import com.njcn.harmonic.pojo.vo.OverAreaLimitVO;
import com.njcn.harmonic.pojo.vo.OverAreaVO;
import com.njcn.harmonic.pojo.vo.WarningSubstationVO;
import com.njcn.harmonic.service.IAnalyzeService;
import com.njcn.influxdb.utils.InfluxDbUtils;
import com.njcn.poi.excel.ExcelUtil;
import com.njcn.web.utils.RequestUtil;
import lombok.AllArgsConstructor;
import org.influxdb.dto.QueryResult;
import org.influxdb.impl.InfluxDBResultMapper;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 类的介绍：
 *
 * @author xuyang
 * @version 1.0.0
 * @createTime 2022/4/29 14:48
 */
@Service
@AllArgsConstructor
public class AnalyzeServiceImpl implements IAnalyzeService {

    private final GeneralDeviceInfoClient generalDeviceInfoClient;

    private final GeneralInfo generalInfo;

    private final HarmonicServiceImpl harmonicService;

    private final InfluxDbUtils influxDbUtils;

    private final LineFeignClient lineFeignClient;

    @Override
    public  Page<OverAreaLimitVO> getAreaData(OverAreaVO param) {
        Page<OverAreaLimitVO> page = new Page<>();
        page.setSize(param.getPageSize());
        page.setCurrent(param.getPageNum());
        List<OverAreaLimitVO> list = new ArrayList<>();
        param.setServerName(generalInfo.getMicroServiceName());
        List<GeneralDeviceDTO> deptList = generalDeviceInfoClient.getPracticalRunDeviceInfo(param).getData();
        if (!CollectionUtils.isEmpty(deptList)){
            page.setTotal(deptList.size());
            int pages = (int)Math.ceil(deptList.size()*1.0/param.getPageSize());
            page.setPages(pages);
            List<List<GeneralDeviceDTO>> pageList = Lists.partition(deptList,param.getPageSize());
            List<GeneralDeviceDTO> temList = pageList.get(param.getPageNum()-1);
            temList.forEach(item->{
                OverAreaLimitVO overAreaLimitVO = new OverAreaLimitVO();
                if (!CollectionUtils.isEmpty(item.getLineIndexes())){
                    List<LimitTarget> limitTargetList = harmonicService.getLimitTarget(item.getLineIndexes(),param.getSearchBeginTime(),param.getSearchEndTime());
                    overAreaLimitVO = handleAreaData(limitTargetList,item.getLineIndexes(),param);
                }
                overAreaLimitVO.setName(item.getName());
                list.add(overAreaLimitVO);
            });
            if (!CollectionUtils.isEmpty(list)){
                List<OverAreaLimitVO> recordList = new ArrayList<>();
                //默认 根据在线监测点个数 倒叙排序
                recordList = list.stream().sorted(Comparator.comparing(OverAreaLimitVO::getOnlineMonitorNumber).reversed().thenComparing(OverAreaLimitVO::getName)).collect(Collectors.toList());
                page.setRecords(recordList);
                return page;
            }
        }
        return page;
    }

    @Override
    @SuppressWarnings("unchecked")
    public Page<WarningSubstationVO> getWarningSubstation(OverAreaVO param) {
        Page<WarningSubstationVO> page = new Page<>();
        page.setSize(param.getPageSize());
        page.setCurrent(param.getPageNum());
        List<String> line = new ArrayList<>(),subInfo = new ArrayList<>();
        List<WarningSubstationDTO> substationDTOList = new ArrayList<>();
        Map<String,List<LimitRate>> map = new HashMap<>();
        Map<String,List<EventDetail>> map2 = new HashMap<>();
        param.setServerName(generalInfo.getMicroServiceName());
        List<WarningSubstationVO> list = new ArrayList<>();
        List<GeneralDeviceDTO> subList = generalDeviceInfoClient.getPracticalRunDeviceInfoAsSubstation(param).getData();
        if (!CollectionUtils.isEmpty(subList)){
            page.setTotal(subList.size());
            int pages = (int)Math.ceil(subList.size()*1.0/param.getPageSize());
            page.setPages(pages);
            List<List<GeneralDeviceDTO>> pageList = Lists.partition(subList,param.getPageSize());
            List<GeneralDeviceDTO> temList = pageList.get(param.getPageNum()-1);
            temList.forEach(item->{
                line.addAll(item.getLineIndexes());
                subInfo.add(item.getIndex());
            });
            if (!CollectionUtils.isEmpty(line)){
                substationDTOList =  lineFeignClient.getWarningSub(subInfo).getData();
                List<LimitRate> limitRateList = (List<LimitRate>)getAllData(line,param.getSearchBeginTime(),param.getSearchEndTime(),Param.LIMIT_RATE);
                if (!CollectionUtils.isEmpty(limitRateList)){
                    map = limitRateList.stream().collect(Collectors.groupingBy(LimitRate::getLineId));
                }
                List<EventDetail> eventDetailList = getEventDetail(line,param.getSearchBeginTime(),param.getSearchEndTime());
                if (!CollectionUtils.isEmpty(eventDetailList)){
                    map2 = eventDetailList.stream().collect(Collectors.groupingBy(EventDetail::getLineId));
                }
            }
            for (GeneralDeviceDTO item : temList) {
                int onlineMonitorCount = 0,alertMonitorCount = 0,alertCount = 0,freqCount = 0,voltageCount = 0,ubalanceCount = 0,flickerCount = 0,iNegCount = 0,uharmCount = 0,iharmCount = 0,inuharmCount = 0;
                int freqCounts = 0,voltageCounts = 0,uharmCounts = 0,iharmCounts = 0,ubalanceCounts = 0,flickerCounts = 0,inuharmCounts = 0,iNegCounts = 0;
                int eventUp = 0,eventDown = 0,eventInterrupt = 0,eventUps = 0,eventDowns = 0,eventInterrupts = 0;
                WarningSubstationVO warningSubstationVO = new WarningSubstationVO();
                //电站id
                warningSubstationVO.setId(item.getIndex());
                //电站名称
                warningSubstationVO.setPlantName(item.getName());
                List<String> lineList = item.getLineIndexes();
                if (!CollectionUtils.isEmpty(lineList)){
                    for (String item2 : lineList) {
                        //谐波统计
                        if (!CollectionUtils.isEmpty(map.get(item2))){
                            LimitRate limitRate = map.get(item2).get(0);
                            if (!Objects.isNull(limitRate)){
                                onlineMonitorCount++;
                                if (limitRate.getFreqDevOverTime() > 0 || limitRate.getVoltageDevOverTime() > 0 || limitRate.getUBalanceOverTime() > 0 || limitRate.getFlickerOverTime() > 0 || limitRate.getINegOverTime() > 0 || limitRate.getUHarm2OverTime() > 0 || limitRate.getIHarm2OverTime() > 0 || limitRate.getInuHarm1OverTime() > 0){
                                    alertMonitorCount++;
                                }
                                if (limitRate.getFreqDevOverTime() > 0){
                                    freqCount++;
                                    freqCounts = freqCounts + limitRate.getFreqDevOverTime();
                                }
                                if (limitRate.getVoltageDevOverTime() > 0){
                                    voltageCount++;
                                    voltageCounts = voltageCounts + limitRate.getVoltageDevOverTime();
                                }
                                if (limitRate.getUHarm2OverTime() > 0){
                                    uharmCount++;
                                    uharmCounts = uharmCounts + limitRate.getUHarm2OverTime();
                                }
                                if (limitRate.getIHarm2OverTime() > 0){
                                    iharmCount++;
                                    iharmCounts = iharmCounts + limitRate.getIHarm2OverTime();
                                }
                                if (limitRate.getUBalanceOverTime() > 0){
                                    ubalanceCount++;
                                    ubalanceCounts = ubalanceCounts + limitRate.getUBalanceOverTime();
                                }
                                if (limitRate.getFlickerOverTime() > 0){
                                    flickerCount++;
                                    flickerCounts = flickerCounts + limitRate.getFlickerOverTime();
                                }
                                if (limitRate.getInuHarm1OverTime() > 0){
                                    inuharmCount++;
                                    inuharmCounts = inuharmCounts + limitRate.getInuHarm1OverTime();
                                }
                                if (limitRate.getINegOverTime() > 0){
                                    iNegCount++;
                                    iNegCounts = iNegCounts + limitRate.getINegOverTime();
                                }
                                alertCount = limitRate.getFreqDevOverTime() + limitRate.getVoltageDevOverTime() + limitRate.getUBalanceOverTime() + limitRate.getFlickerOverTime() + limitRate.getINegOverTime() + limitRate.getUHarm2OverTime() + limitRate.getIHarm2OverTime() + limitRate.getInuHarm1OverTime();
                            }
                        }
                        //暂降统计
                        if (!CollectionUtils.isEmpty(map2.get(item2))){
                            List<EventDetail> eventDetailList = map2.get(item2);
                            if (!CollectionUtils.isEmpty(eventDetailList)){
                                for (EventDetail item3 : eventDetailList) {
                                    if (item3.getWaveType() == 1){
                                        eventDowns++;
                                    } else if (item3.getWaveType() == 2){
                                        eventUps++;
                                    } else if (item3.getWaveType() == 3){
                                        eventInterrupts++;
                                    }
                                }
                            }
                        }
                        if (eventDowns > 0){
                            eventDown++;
                        }
                        if (eventUps > 0){
                            eventUp++;
                        }
                        if (eventInterrupts > 0){
                            eventInterrupt++;
                        }
                    }
                }
                //在线监测点数量(个)
                warningSubstationVO.setOnlineMonitorCounts(onlineMonitorCount);
                if (onlineMonitorCount != 0){
                    //告警监测点数量(个)
                    warningSubstationVO.setAlertMonitorCounts(alertMonitorCount);
                    //告警次数
                    warningSubstationVO.setAlertCounts(alertCount);
                    //告警频次(次/点)
                    warningSubstationVO.setAlertAlarmFrequency(alertMonitorCount==0?0:BigDecimal.valueOf(alertCount*1.0/alertMonitorCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //频率偏差
                    warningSubstationVO.setFrequencyDeviation(freqCount==0?0:BigDecimal.valueOf(freqCounts*1.0/freqCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //电压偏差
                    warningSubstationVO.setVoltageDeviation(voltageCount==0?0:BigDecimal.valueOf(voltageCounts*1.0/voltageCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //谐波电压
                    warningSubstationVO.setHarmonicVoltage(uharmCount==0?0:BigDecimal.valueOf(uharmCounts*1.0/uharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //谐波电流
                    warningSubstationVO.setHarmonicCurrent(iharmCount==0?0:BigDecimal.valueOf(iharmCounts*1.0/iharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //三相电压不平衡
                    warningSubstationVO.setThreePhaseVoltageUnbalance(ubalanceCount==0?0:BigDecimal.valueOf(ubalanceCounts*1.0/ubalanceCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //闪变
                    warningSubstationVO.setFlicker(flickerCount==0?0:BigDecimal.valueOf(flickerCounts*1.0/flickerCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //间谐波电压
                    warningSubstationVO.setInterHarmonic(inuharmCount==0?0:BigDecimal.valueOf(inuharmCounts*1.0/inuharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //负序电流
                    warningSubstationVO.setNegative(iNegCount==0?0:BigDecimal.valueOf(iNegCounts*1.0/iNegCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //电压暂降
                    warningSubstationVO.setVoltageDip(eventDown==0?0:BigDecimal.valueOf(eventDowns*1.0/eventDown).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //电压暂升
                    warningSubstationVO.setVoltageSwell(eventUp==0?0:BigDecimal.valueOf(eventUps*1.0/eventUp).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //短时中断
                    warningSubstationVO.setShortInterruption(eventInterrupt==0?0:BigDecimal.valueOf(eventInterrupts*1.0/eventInterrupt).setScale(2, RoundingMode.HALF_UP).doubleValue());
                }
                list.add(warningSubstationVO);
            }
        }
        if (!CollectionUtils.isEmpty(list)){
            for (WarningSubstationVO item1 : list) {
                for (WarningSubstationDTO item2 : substationDTOList) {
                    if (Objects.equals(item1.getId(),item2.getId())){
                        item1.setProvinceCompany(item2.getProvince());
                        item1.setCityCompany(item2.getCity());
                        item1.setPlantVoltageLevel(item2.getScale());
                    }
                }
            }
            List<WarningSubstationVO> recordList = new ArrayList<>();
            //默认 在线监测点数量 倒叙排序
            recordList = list.stream().sorted(Comparator.comparing(WarningSubstationVO::getOnlineMonitorCounts).reversed().thenComparing(WarningSubstationVO::getPlantName)).collect(Collectors.toList());
            page.setRecords(recordList);
            return page;
        }
        return page;
    }

    @Override
    public Page<MonitorOverLimitVO> monitorOverLimitVO(OverAreaVO param) {
        Page<MonitorOverLimitVO> page = new Page<>();
        page.setSize(param.getPageSize());
        page.setCurrent(param.getPageNum());
        List<MonitorOverLimitVO> result = new ArrayList<>();
        List<String> lineList = new ArrayList<>();
        List<GeneralDeviceDTO> deptList = generalDeviceInfoClient.getPracticalRunDeviceInfo(param).getData();
        if (!CollectionUtils.isEmpty(deptList)){
            deptList.forEach(item->{
                lineList.addAll(item.getLineIndexes());
            });
        }
        if (!CollectionUtils.isEmpty(lineList)){
            page.setTotal(lineList.size());
            int pages = (int)Math.ceil(lineList.size()*1.0/param.getPageSize());
            page.setPages(pages);
            List<List<String>> pageList = Lists.partition(lineList,param.getPageSize());
            List<String> temList = pageList.get(param.getPageNum()-1);
            List<LimitTarget> limitTargetList = getOverDays(temList,param.getSearchBeginTime(),param.getSearchEndTime());
            Map<String,List<LimitTarget>> map = limitTargetList.stream().collect(Collectors.groupingBy(LimitTarget::getLineId));
            PollutionParamDTO pollutionParamDTO = new PollutionParamDTO();
            pollutionParamDTO.setLineList(temList);
            List<OverLimitLineDTO> overLimitLineList = lineFeignClient.getOverLimitLineInfo(pollutionParamDTO).getData();
            overLimitLineList.forEach(item->{
                int overDay=0,freqOverDay=0,volDevOverDay=0,threeUnbalance=0,flickerOverDay=0,negativeOverDay=0,harmVolOverDay=0,volDisOverDay=0,volContainOverDay=0,harmCurOverDay=0,intHarmOverDay=0;
                int overVolThreeTimes=0,overVolFiveTimes=0,overVolSevenTimes=0,overVolElevenTimes=0,overVolThirteenTimes=0,overVolTwentyThreeTimes=0,overVolTwentyFiveTimes=0,overVolOtherTimes=0;
                int overCurThreeTimes=0,overCurFiveTimes=0,overCurSevenTimes=0,overCurElevenTimes=0,overCurThirteenTimes=0,overCurTwentyThreeTimes=0,overCurTwentyFiveTimes=0,overCurOtherTimes=0;
                MonitorOverLimitVO monitorOverLimitVO = new MonitorOverLimitVO();
                BeanUtil.copyProperties(item,monitorOverLimitVO);
                List<LimitTarget> l1 = map.get(item.getId());
                if (!CollectionUtils.isEmpty(l1)){
                    for (LimitTarget item2 : l1) {
                        if (item2.getFreqDevOverTime()+item2.getVoltageDevOverTime()+item2.getUBalanceOverTime()+item2.getFlickerOverTime()+item2.getINegOverTime()+item2.getUAberranceOverTime()+item2.getUHarmAllOverTime()+item2.getIHarmAllOverTime()+item2.getInuharmAllOverTime() > 0){
                            overDay++;
                        }
                        if (item2.getFreqDevOverTime()>0){
                            freqOverDay++;
                        }
                        if (item2.getVoltageDevOverTime()>0){
                            volDevOverDay++;
                        }
                        if (item2.getUBalanceOverTime()>0){
                            threeUnbalance++;
                        }
                        if (item2.getFlickerOverTime()>0){
                            flickerOverDay++;
                        }
                        if (item2.getINegOverTime()>0){
                            negativeOverDay++;
                        }
                        if (item2.getUAberranceOverTime()+item2.getUHarmAllOverTime()>0){
                            harmVolOverDay++;
                        }
                        if (item2.getUAberranceOverTime()>0){
                            volDisOverDay++;
                        }
                        if (item2.getUHarmAllOverTime()>0){
                            volContainOverDay++;
                        }
                        if (item2.getIHarmAllOverTime()>0){
                            harmCurOverDay++;
                        }
                        if (item2.getInuharmAllOverTime()>0){
                            intHarmOverDay++;
                        }
                        if (item2.getUHarm3OverTime()>0){
                            overVolThreeTimes++;
                        }
                        if (item2.getUHarm5OverTime()>0){
                            overVolFiveTimes++;
                        }
                        if (item2.getUHarm7OverTime()>0){
                            overVolSevenTimes++;
                        }
                        if (item2.getUHarm11OverTime()>0){
                            overVolElevenTimes++;
                        }
                        if (item2.getUHarm13OverTime()>0){
                            overVolThirteenTimes++;
                        }
                        if (item2.getUHarm23OverTime()>0){
                            overVolTwentyThreeTimes++;
                        }
                        if (item2.getUHarm25OverTime()>0){
                            overVolTwentyFiveTimes++;
                        }
                        if (item2.getUHarmAllOverTime()>0){
                            overVolOtherTimes++;
                        }
                        if (item2.getIHarm3OverTime()>0){
                            overCurThreeTimes++;
                        }
                        if (item2.getIHarm5OverTime()>0){
                            overCurFiveTimes++;
                        }
                        if (item2.getIHarm7OverTime()>0){
                            overCurSevenTimes++;
                        }
                        if (item2.getIHarm11OverTime()>0){
                            overCurElevenTimes++;
                        }
                        if (item2.getIHarm13OverTime()>0){
                            overCurThirteenTimes++;
                        }
                        if (item2.getIHarm23OverTime()>0){
                            overCurTwentyThreeTimes++;
                        }
                        if (item2.getIHarm25OverTime()>0){
                            overCurTwentyFiveTimes++;
                        }
                        if (item2.getIHarmAllOverTime()>0){
                            overCurOtherTimes++;
                        }
                    }
                }
                monitorOverLimitVO.setOverDay(overDay);
                monitorOverLimitVO.setFreqOverDay(freqOverDay);
                monitorOverLimitVO.setVolDevOverDay(volDevOverDay);
                monitorOverLimitVO.setThreeUnbalance(threeUnbalance);
                monitorOverLimitVO.setFlickerOverDay(flickerOverDay);
                monitorOverLimitVO.setNegativeOverDay(negativeOverDay);
                monitorOverLimitVO.setHarmVolOverDay(harmVolOverDay);
                monitorOverLimitVO.setVolDisOverDay(volDisOverDay);
                monitorOverLimitVO.setVolContainOverDay(volContainOverDay);
                monitorOverLimitVO.setHarmCurOverDay(harmCurOverDay);
                monitorOverLimitVO.setIntHarmOverDay(intHarmOverDay);
                monitorOverLimitVO.setOverVolThreeTimes(overVolThreeTimes);
                monitorOverLimitVO.setOverVolFiveTimes(overVolFiveTimes);
                monitorOverLimitVO.setOverVolSevenTimes(overVolSevenTimes);
                monitorOverLimitVO.setOverVolElevenTimes(overVolElevenTimes);
                monitorOverLimitVO.setOverVolThirteenTimes(overVolThirteenTimes);
                monitorOverLimitVO.setOverVolTwentyThreeTimes(overVolTwentyThreeTimes);
                monitorOverLimitVO.setOverVolTwentyFiveTimes(overVolTwentyFiveTimes);
                monitorOverLimitVO.setOverVolOtherTimes(overVolOtherTimes);
                monitorOverLimitVO.setOverCurThreeTimes(overCurThreeTimes);
                monitorOverLimitVO.setOverCurFiveTimes(overCurFiveTimes);
                monitorOverLimitVO.setOverCurSevenTimes(overCurSevenTimes);
                monitorOverLimitVO.setOverCurElevenTimes(overCurElevenTimes);
                monitorOverLimitVO.setOverCurThirteenTimes(overCurThirteenTimes);
                monitorOverLimitVO.setOverCurTwentyThreeTimes(overCurTwentyThreeTimes);
                monitorOverLimitVO.setOverCurTwentyFiveTimes(overCurTwentyFiveTimes);
                monitorOverLimitVO.setOverCurOtherTimes(overCurOtherTimes);
                result.add(monitorOverLimitVO);
            });
        }
        if (!CollectionUtils.isEmpty(result)){
            List<MonitorOverLimitVO> recordList = new ArrayList<>();
            //默认 根据在线监测点个数 倒叙排序
            recordList = result.stream().sorted(Comparator.comparing(MonitorOverLimitVO::getOverDay).reversed()).collect(Collectors.toList());
            page.setRecords(recordList);
            return page;
        }
        return page;
    }

    @Override
    public String exportArea(OverAreaVO param, String methodDescribe) {
        List<AreaExcel> result = new ArrayList<>();
        String fileName = methodDescribe + "_" + param.getSearchBeginTime()+ "-" + param.getSearchEndTime() + "_" + param.getStatisticalType().getName() +".xlsx";
        String targetDir = generalInfo.getBusinessTempPath() + File.separator + RequestUtil.getUserIndex();
        File excel = new File(targetDir, fileName);
        List<OverAreaLimitVO> list = getAreaData(param).getRecords();
        if (!CollectionUtil.isEmpty(list)) {
            list.forEach(item->{
                AreaExcel areaExcel = new AreaExcel();
                BeanUtil.copyProperties(item,areaExcel);
                result.add(areaExcel);
            });
        }
        ExcelUtil.exportExcelWithTargetFile(excel, param.getStatisticalType().getName(), methodDescribe, AreaExcel.class, result);
        return FileUtil.getAbsolutePath(excel);
    }


    /**
     * 功能描述: 处理区域(变电站)在线监测点数、超标监测点数、平均超标天数、占比
     * @param list 集合
     *        type 类型
     * @return
     * @author xy
     * @date 2022/2/25 15:05
     */
    @SuppressWarnings("unchecked")
    public OverAreaLimitVO handleAreaData(List<LimitTarget> list, List<String> line, OverAreaVO param) {
        int onlineCount = 0,overLineCount = 0,freqCount = 0,voltageCount = 0,ubalanceCount = 0,flickerCount = 0,iNegCount = 0,uharmCount = 0,iharmCount = 0,inuharmCount = 0;
        int freqOverDay = 0,voltageOverDay = 0, ubalanceOverDay = 0,flickerOverDay = 0,iNegOverDay = 0,uharmOverDay = 0,iharmOverDay = 0,inuharmOverDay = 0;
        OverAreaLimitVO overAreaLimitVO = new OverAreaLimitVO();
        if (!CollectionUtils.isEmpty(list)){
            List<LimitTarget> data = (List<LimitTarget>)getAllData(line,param.getSearchBeginTime(),param.getSearchEndTime(),Param.LIMIT_TARGET);
            if (!CollectionUtils.isEmpty(data)) {
                onlineCount = data.size();
                //在线监测点个数
                overAreaLimitVO.setOnlineMonitorNumber(onlineCount);
                for (LimitTarget item : data) {
                    if (item.getFreqDevOverTime() > 0 || item.getVoltageDevOverTime() > 0 || item.getUBalanceOverTime() > 0 || item.getFlickerOverTime() > 0 || item.getINegOverTime() > 0 ||item.getUHarm2OverTime() > 0 || item.getIHarm2OverTime() > 0 || item.getInuHarm1OverTime() > 0) {
                        overLineCount++;
                    }
                    if (item.getFreqDevOverTime() > 0){
                        freqCount++;
                    }
                    if (item.getVoltageDevOverTime() > 0){
                        voltageCount++;
                    }
                    if (item.getUBalanceOverTime() > 0){
                        ubalanceCount++;
                    }
                    if (item.getFlickerOverTime() > 0){
                        flickerCount++;
                    }
                    if (item.getINegOverTime() > 0){
                        iNegCount++;
                    }
                    if (item.getUHarm2OverTime() > 0){
                        uharmCount++;
                    }
                    if (item.getIHarm2OverTime() > 0){
                        iharmCount++;
                    }
                    if (item.getInuHarm1OverTime() > 0){
                        inuharmCount++;
                    }
                }
                //超标监测点个数
                overAreaLimitVO.setOverLimitMonitorNumber(overLineCount);
                //超标监测点数占比
                overAreaLimitVO.setOverBiLi(BigDecimal.valueOf(overLineCount*1.0/data.size()).setScale(2, RoundingMode.HALF_UP).doubleValue());
                //频率偏差
                overAreaLimitVO.setFrequencyMonitorNumber(freqCount);
                overAreaLimitVO.setFrequencyBiLi(BigDecimal.valueOf(freqCount*1.0/data.size()).setScale(2, RoundingMode.HALF_UP).doubleValue());
                //电压偏差
                overAreaLimitVO.setVoltageMonitorNumber(voltageCount);
                overAreaLimitVO.setVoltageBiLi(BigDecimal.valueOf(voltageCount*1.0/data.size()).setScale(2, RoundingMode.HALF_UP).doubleValue());
                //谐波电压
                overAreaLimitVO.setHarmonicVoltageMonitorNumber(uharmCount);
                overAreaLimitVO.setHarmonicVoltageBiLi(BigDecimal.valueOf(uharmCount*1.0/data.size()).setScale(2, RoundingMode.HALF_UP).doubleValue());
                //谐波电流
                overAreaLimitVO.setHarmonicCurrentMonitorNumber(iharmCount);
                overAreaLimitVO.setHarmonicCurrentBiLi(BigDecimal.valueOf(iharmCount*1.0/data.size()).setScale(2, RoundingMode.HALF_UP).doubleValue());
                //三相电压不平衡度
                overAreaLimitVO.setThreePhaseVoltageMonitorNumber(ubalanceCount);
                overAreaLimitVO.setThreePhaseVoltageBiLi(BigDecimal.valueOf(ubalanceCount*1.0/data.size()).setScale(2, RoundingMode.HALF_UP).doubleValue());
                //闪变
                overAreaLimitVO.setFlickerMonitorNumber(flickerCount);
                overAreaLimitVO.setFlickerBiLi(BigDecimal.valueOf(flickerCount*1.0/data.size()).setScale(2, RoundingMode.HALF_UP).doubleValue());
                //负序电流
                overAreaLimitVO.setNegativeMonitorNumber(iNegCount);
                overAreaLimitVO.setNegativeBiLi(BigDecimal.valueOf(flickerCount*1.0/data.size()).setScale(2, RoundingMode.HALF_UP).doubleValue());
                //间谐波电压
                overAreaLimitVO.setInterHarmonicMonitorNumber(inuharmCount);
                overAreaLimitVO.setInterHarmonicBiLi(BigDecimal.valueOf(inuharmCount*1.0/data.size()).setScale(2, RoundingMode.HALF_UP).doubleValue());
            }
        }
        Map<Instant,List<LimitTarget>> map = list.stream().collect(Collectors.groupingBy(LimitTarget::getTime));
        for (Instant key : map.keySet()) {
            List<LimitTarget> l = map.get(key);
            for (LimitTarget pojo : l) {
                if (pojo.getFreqDevOverTime() > 0){
                    freqOverDay++;
                }
                if (pojo.getVoltageDevOverTime() > 0){
                    voltageOverDay++;
                }
                if (pojo.getUBalanceOverTime() > 0){
                    ubalanceOverDay++;
                }
                if (pojo.getFlickerOverTime() > 0){
                    flickerOverDay++;
                }
                if (pojo.getINegOverTime() > 0){
                    iNegOverDay++;
                }
                if (pojo.getUHarm2OverTime() > 0){
                    uharmOverDay++;
                }
                if (pojo.getIHarm2OverTime() > 0){
                    iharmOverDay++;
                }
                if (pojo.getInuHarm1OverTime() > 0){
                    inuharmOverDay++;
                }
            }
        }
        if (onlineCount != 0){
            overAreaLimitVO.setFrequencyOverDayBiLi(freqCount == 0?0.0:BigDecimal.valueOf(freqOverDay*1.0/freqCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
            overAreaLimitVO.setVoltageOverDayBiLi(voltageCount == 0?0.0:BigDecimal.valueOf(voltageOverDay*1.0/voltageCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
            overAreaLimitVO.setThreePhaseVoltageOverDayBiLi(ubalanceCount == 0?0.0:BigDecimal.valueOf(ubalanceOverDay*1.0/ubalanceCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
            overAreaLimitVO.setFlickerOverDayBiLi(flickerCount == 0?0.0:BigDecimal.valueOf(flickerOverDay*1.0/flickerCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
            overAreaLimitVO.setNegativeOverDayBiLi(iNegCount == 0?0.0:BigDecimal.valueOf(iNegOverDay*1.0/iNegCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
            overAreaLimitVO.setHarmonicVoltageOverDayBiLi(uharmCount == 0?0.0:BigDecimal.valueOf(uharmOverDay*1.0/uharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
            overAreaLimitVO.setHarmonicCurrentOverDayBiLi(iharmCount == 0?0.0:BigDecimal.valueOf(iharmOverDay*1.0/iharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
            overAreaLimitVO.setInterHarmonicOverDayBiLi(inuharmCount == 0?0.0:BigDecimal.valueOf(inuharmOverDay*1.0/inuharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
        }
        return overAreaLimitVO;
    }

    /**
     * 功能描述: 处理区域在线监测点数、超标监测点数
     * @param list 集合
     * @return
     * @author xy
     * @date 2022/2/25 15:05
     */
    private List<?> getAllData(List<String> list, String startTime, String endTime, String databaseName){
        List<?> result = new ArrayList<>();
        StringBuilder stringBuilder = new StringBuilder();
        StringBuilder stringBuilder1 = new StringBuilder();
        stringBuilder.append(Param.TIME + " >= '").append(startTime).append("' and ").append(Param.TIME).append(" <= '").append(endTime).append("' and (");
        for (int i=0;i<list.size();i++){
            if (list.size() - i != 1){
                stringBuilder.append(Param.LINE_ID + "='").append(list.get(i)).append("' or ");
            } else {
                stringBuilder.append(Param.LINE_ID + "='").append(list.get(i)).append("')");
            }
        }
        stringBuilder.append(" group by line_id tz('Asia/Shanghai')");
        stringBuilder1.append("sum(freq_dev_overtime) AS freq_dev_overtime,sum(voltage_dev_overtime) AS voltage_dev_overtime,sum(ubalance_overtime) AS ubalance_overtime,sum(flicker_overtime) AS flicker_overtime,sum(i_neg_overtime) AS i_neg_overtime,");
        stringBuilder1.append("sum(uaberrance_overtime)+");
        for (int i = 2; i <= 25; i++) {
            if (i==25){
                stringBuilder1.append("sum(uharm_").append(i).append("_overtime) AS ").append("uharm_2").append("_overtime,");
            } else {
                stringBuilder1.append("sum(uharm_").append(i).append("_overtime)+");
            }
        }
        for (int i = 2; i <= 25; i++) {
            if (i==25){
                stringBuilder1.append("sum(iharm_").append(i).append("_overtime) AS ").append("iharm_2").append("_overtime,");
            } else {
                stringBuilder1.append("sum(iharm_").append(i).append("_overtime)+");
            }
        }
        for (int i = 1; i <= 16; i++) {
            if (i==16){
                stringBuilder1.append("sum(inuharm_").append(i).append("_overtime) AS ").append("inuharm_1").append("_overtime");
            } else {
                stringBuilder1.append("sum(inuharm_").append(i).append("_overtime)+");
            }
        }
        String sql = "select "+stringBuilder1+" from "+databaseName+" where " + stringBuilder;
        QueryResult sqlResult = influxDbUtils.query(sql);
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        switch (databaseName) {
            case Param.LIMIT_TARGET:
                result = resultMapper.toPOJO(sqlResult,LimitTarget.class);
                break;
            case Param.LIMIT_RATE:
                result = resultMapper.toPOJO(sqlResult,LimitRate.class);
                break;
            default:
                break;
        }
        return result;
    }

    public List<EventDetail> getEventDetail(List<String> list, String startTime, String endTime){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(Param.TIME + " >= '").append(startTime).append("' and ").append(Param.TIME).append(" <= '").append(endTime).append("' and (");
        for (int i=0;i<list.size();i++){
            if (list.size() - i != 1){
                stringBuilder.append(Param.LINE_ID + "='").append(list.get(i)).append("' or ");
            } else {
                stringBuilder.append(Param.LINE_ID + "='").append(list.get(i)).append("')");
            }
        }
        stringBuilder.append(" group by line_id tz('Asia/Shanghai')");
        String sql = "select * from pqs_eventdetail where " + stringBuilder;
        QueryResult sqlResult = influxDbUtils.query(sql);
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        return resultMapper.toPOJO(sqlResult, EventDetail.class);
    }

    public List<LimitTarget> getOverDays(List<String> list, String startTime, String endTime){
        StringBuilder stringBuilder = new StringBuilder();
        StringBuilder stringBuilder1 = new StringBuilder();
        stringBuilder.append(Param.TIME + " >= '").append(startTime).append("' and ").append(Param.TIME).append(" <= '").append(endTime).append("' and (");
        for (int i=0;i<list.size();i++){
            if (list.size() - i != 1){
                stringBuilder.append(Param.LINE_ID + "='").append(list.get(i)).append("' or ");
            } else {
                stringBuilder.append(Param.LINE_ID + "='").append(list.get(i)).append("')");
            }
        }
        stringBuilder.append(" group by line_id tz('Asia/Shanghai')");
        stringBuilder1.append("freq_dev_overtime AS freq_dev_overtime,voltage_dev_overtime AS voltage_dev_overtime,ubalance_overtime AS ubalance_overtime,flicker_overtime AS flicker_overtime,i_neg_overtime AS i_neg_overtime,uaberrance_overtime AS uaberrance_overtime,");
        for (int i = 2; i <= 25; i++) {
            if (i==25){
                stringBuilder1.append("uharm_").append(i).append("_overtime AS uharm_all_overtime,");
            } else {
                stringBuilder1.append("uharm_").append(i).append("_overtime+");
            }
        }
        for (int i = 2; i <= 25; i++) {
            if (i==25){
                stringBuilder1.append("iharm_").append(i).append("_overtime AS iharm_all_overtime,");
            } else {
                stringBuilder1.append("iharm_").append(i).append("_overtime+");
            }
        }
        for (int i = 1; i <= 16; i++) {
            if (i==16){
                stringBuilder1.append("inuharm_").append(i).append("_overtime AS inuharm_all_overtime,");
            } else {
                stringBuilder1.append("inuharm_").append(i).append("_overtime+");
            }
        }
        stringBuilder1.append("uharm_3_overtime,uharm_5_overtime,uharm_7_overtime,uharm_11_overtime,uharm_13_overtime,uharm_23_overtime,uharm_25_overtime,");
        for (int i = 2; i <= 25; i++) {
            if (i!=3 && i!=5 && i!=7 && i!=11 && i!=13 && i!=23 && i!=25){
                if (i==24){
                    stringBuilder1.append("uharm_").append(i).append("_overtime AS uOtherTimes,");
                } else {
                    stringBuilder1.append("uharm_").append(i).append("_overtime+");
                }
            }
        }
        stringBuilder1.append("iharm_3_overtime,iharm_5_overtime,iharm_7_overtime,iharm_11_overtime,iharm_13_overtime,iharm_23_overtime,iharm_25_overtime,");
        for (int i = 2; i <= 25; i++) {
            if (i!=3 && i!=5 && i!=7 && i!=11 && i!=13 && i!=23 && i!=25){
                if (i==24){
                    stringBuilder1.append("iharm_").append(i).append("_overtime AS iOtherTimes");
                } else {
                    stringBuilder1.append("iharm_").append(i).append("_overtime+");
                }
            }
        }
        String sql = "select "+stringBuilder1+" from limit_target where " + stringBuilder;
        QueryResult sqlResult = influxDbUtils.query(sql);
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        return resultMapper.toPOJO(sqlResult, LimitTarget.class);
    }
}
