package com.njcn.executor.handler;

import com.njcn.device.api.LineFeignClient;
import com.njcn.device.pojo.po.Overlimit;
import com.njcn.executor.pojo.dto.PollutionDTO;
import com.njcn.executor.pojo.vo.*;
import com.njcn.harmonic.pojo.dto.PublicDTO;
import com.njcn.influxdb.utils.InfluxDbUtils;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.influxdb.InfluxDB;
import org.influxdb.dto.BatchPoints;
import org.influxdb.dto.Point;
import org.influxdb.dto.QueryResult;
import org.influxdb.impl.InfluxDBResultMapper;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author xuy
 * @version 1.0.0
 * @date 2022年04月07日 09:54
 */
@Slf4j
@Component
@AllArgsConstructor
public class PollutionJob {

    private final String DATABASE = "pqsbase";

    private final InfluxDbUtils influxDbUtils;

    private final LineFeignClient lineFeignClient;

    /**
     * 监测点污染指标
     */
    @XxlJob("pollutionJobHandler")
    public void pollutionJobHandler() {
        List<PublicDTO> list = new ArrayList<>();
        //谐波电压
        List<PublicDTO> uaberranceList = new ArrayList<>();
        //谐波电流
        List<PublicDTO> iHarmList = new ArrayList<>();
        //频率偏差
        List<PublicDTO> freqList = new ArrayList<>();
        //电压偏差
        List<PublicDTO> devList = new ArrayList<>();
        //三相电压不平衡度
        List<PublicDTO> uBalanceList = new ArrayList<>();
        //负序电流
        List<PublicDTO> iNegList = new ArrayList<>();
        //间谐波电压含有率
        List<PublicDTO> iNuharmList = new ArrayList<>();
        //长时电压闪变
        List<PublicDTO> flickerList = new ArrayList<>();
        List<String> lineList = getAllLinesLimitData().stream().map(Overlimit::getId).collect(Collectors.toList());
        List<PollutionDTO> pollutionList = new ArrayList<>();
        lineList.forEach(item->{
            PollutionDTO pollutionDTO = new PollutionDTO();
            pollutionDTO.setId(item);
            pollutionList.add(pollutionDTO);
        });
        //谐波电压污染数值
        Map<String, Optional<PublicDTO>> map1 = getDistortionData();
        for (String key : map1.keySet()) {
            list.add(map1.get(key).get());
        }
        Map<String, Optional<PublicDTO>> map2 = getContentData();
        for (String key : map2.keySet()) {
            list.add(map2.get(key).get());
        }
        Comparator<PublicDTO> comparator = Comparator.comparing(PublicDTO::getData);
        Map<String, Optional<PublicDTO>> result = list.stream().collect(Collectors.groupingBy(PublicDTO::getId,Collectors.reducing(BinaryOperator.maxBy(comparator))));
        for (String key : result.keySet()) {
            uaberranceList.add(result.get(key).get());
        }
        //谐波电流污染数值
        Map<String, Optional<PublicDTO>> map3 = getIharm();
        for (String key : map3.keySet()) {
            iHarmList.add(map3.get(key).get());
        }
        //频率偏差污染数值
        Map<String, Optional<PublicDTO>> map4 = getFreq();
        for (String key : map4.keySet()) {
            freqList.add(map4.get(key).get());
        }
        //电压偏差
        Map<String, Optional<PublicDTO>> map5 =  getDev();
        for (String key : map5.keySet()) {
            devList.add(map5.get(key).get());
        }
        //三相电压不平衡度
        Map<String, Optional<PublicDTO>> map6 =  getUbalance();
        for (String key : map6.keySet()) {
            uBalanceList.add(map6.get(key).get());
        }
        //负序电流
        Map<String, Optional<PublicDTO>> map7 =  getIneg();
        for (String key : map7.keySet()) {
            iNegList.add(map7.get(key).get());
        }
        //间谐波电压含有率
        Map<String, Optional<PublicDTO>> map8 =  getInuharm();
        for (String key : map8.keySet()) {
            iNuharmList.add(map8.get(key).get());
        }
        //长时电压闪变
        Map<String, Optional<PublicDTO>> map9 =  getFlicker();
        for (String key : map9.keySet()) {
            flickerList.add(map9.get(key).get());
        }
        //组装数据
        for (PollutionDTO item1 : pollutionList) {
            for (PublicDTO item2 : uaberranceList) {
                if (Objects.equals(item1.getId(),item2.getId())){
                    item1.setData5(BigDecimal.valueOf(item2.getData()).setScale(4, RoundingMode.HALF_UP).doubleValue());
                }
            }
        }
        for (PollutionDTO item1 : pollutionList) {
            for (PublicDTO item2 : iHarmList) {
                if (Objects.equals(item1.getId(),item2.getId())){
                    item1.setData6(BigDecimal.valueOf(item2.getData()).setScale(4, RoundingMode.HALF_UP).doubleValue());
                }
            }
        }
        for (PollutionDTO item1 : pollutionList) {
            for (PublicDTO item2 : freqList) {
                if (Objects.equals(item1.getId(),item2.getId())){
                    item1.setData1(BigDecimal.valueOf(item2.getData()).setScale(4, RoundingMode.HALF_UP).doubleValue());
                }
            }
        }
        for (PollutionDTO item1 : pollutionList) {
            for (PublicDTO item2 : devList) {
                if (Objects.equals(item1.getId(),item2.getId())){
                    item1.setData2(BigDecimal.valueOf(item2.getData()).setScale(4, RoundingMode.HALF_UP).doubleValue());
                }
            }
        }
        for (PollutionDTO item1 : pollutionList) {
            for (PublicDTO item2 : uBalanceList) {
                if (Objects.equals(item1.getId(),item2.getId())){
                    item1.setData3(BigDecimal.valueOf(item2.getData()).setScale(4, RoundingMode.HALF_UP).doubleValue());
                }
            }
        }
        for (PollutionDTO item1 : pollutionList) {
            for (PublicDTO item2 : iNegList) {
                if (Objects.equals(item1.getId(),item2.getId())){
                    item1.setData4(BigDecimal.valueOf(item2.getData()).setScale(4, RoundingMode.HALF_UP).doubleValue());
                }
            }
        }
        for (PollutionDTO item1 : pollutionList) {
            for (PublicDTO item2 : iNuharmList) {
                if (Objects.equals(item1.getId(),item2.getId())){
                    item1.setData7(BigDecimal.valueOf(item2.getData()).setScale(4, RoundingMode.HALF_UP).doubleValue());
                }
            }
        }
        for (PollutionDTO item1 : pollutionList) {
            for (PublicDTO item2 : flickerList) {
                if (Objects.equals(item1.getId(),item2.getId())){
                    item1.setData8(BigDecimal.valueOf(item2.getData()).setScale(4, RoundingMode.HALF_UP).doubleValue());
                }
            }
        }
        //将处理好的数据存入influxDB表中
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH)-1, 0, 0, 0);
        calendar.set(Calendar.MILLISECOND,0);
        createMeasurement(pollutionList,calendar.getTimeInMillis());
    }


    /**
     * 获取限值表中的所有监测点信息
     */
    private List<Overlimit> getAllLinesLimitData() {
        return lineFeignClient.getAllLineOverLimit("harmonic-boot","").getData();
    }

    /**
     * 谐波电压 -> 电压总谐波畸变率
     * 各监测点最新的A、B、C三相数据
     * 按照监测点分组，每个监测点取最大
     */
    private Map<String, Optional<PublicDTO>> getDistortionData(){
        String sql = "SELECT * FROM day_v where value_type = 'CP95' and (phasic_type = 'A' or phasic_type = 'B' or phasic_type = 'C') group by line_id order by time desc limit 3";
        QueryResult sqlResult = influxDbUtils.query(sql);
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        List<Double> data;
        PublicDTO publicDTO;
        List<PublicDTO> lineData = new ArrayList<>();
        List<DayV> list = resultMapper.toPOJO(sqlResult, DayV.class);
        List<Overlimit> overLimitList = getAllLinesLimitData();
        for (DayV item1 : list) {
            for (Overlimit item2 : overLimitList) {
                if (Objects.equals(item1.getLineId(),item2.getId())){
                    double vUnbalance = item1.getVUnbalance()/item2.getUaberrance();
                    data = Stream.of(vUnbalance).collect(Collectors.toList());
                    double result = data.stream().max(Comparator.comparing(Double::doubleValue)).get();
                    publicDTO = new PublicDTO();
                    publicDTO.setId(item1.getLineId());
                    publicDTO.setData(result);
                    lineData.add(publicDTO);
                }
            }
        }
        Comparator<PublicDTO> comparator = Comparator.comparing(PublicDTO::getData);
        return lineData.stream().collect(Collectors.groupingBy(PublicDTO::getId,Collectors.reducing(BinaryOperator.maxBy(comparator))));
    }

    /**
     * 谐波电压 -> 各次谐波电压含有率（2~25次）
     * 各监测点最新的A、B、C三相数据
     */
    private Map<String, Optional<PublicDTO>> getContentData(){
        String sql = "SELECT * FROM day_harmrate_v where value_type = 'CP95' and (phasic_type = 'A' or phasic_type = 'B' or phasic_type = 'C') group by line_id order by time desc limit 3";
        QueryResult sqlResult = influxDbUtils.query(sql);
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        List<Double> data;
        PublicDTO publicDTO;
        List<PublicDTO> lineData = new ArrayList<>();
        List<DayHarmrateV> list = resultMapper.toPOJO(sqlResult, DayHarmrateV.class);
        List<Overlimit> overLimitList = getAllLinesLimitData();
        for (DayHarmrateV dayHarmrateV : list) {
            for (Overlimit overlimit : overLimitList) {
                if (Objects.equals(dayHarmrateV.getLineId(),overlimit.getId())){
                    double v2 = dayHarmrateV.getV2()/overlimit.getUharm2();
                    double v3 = dayHarmrateV.getV3()/overlimit.getUharm3();
                    double v4 = dayHarmrateV.getV4()/overlimit.getUharm4();
                    double v5 = dayHarmrateV.getV5()/overlimit.getUharm5();
                    double v6 = dayHarmrateV.getV6()/overlimit.getUharm6();
                    double v7 = dayHarmrateV.getV7()/overlimit.getUharm7();
                    double v8 = dayHarmrateV.getV8()/overlimit.getUharm8();
                    double v9 = dayHarmrateV.getV9()/overlimit.getUharm9();
                    double v10 = dayHarmrateV.getV10()/overlimit.getUharm10();
                    double v11 = dayHarmrateV.getV11()/overlimit.getUharm11();
                    double v12 = dayHarmrateV.getV12()/overlimit.getUharm12();
                    double v13 = dayHarmrateV.getV13()/overlimit.getUharm13();
                    double v14 = dayHarmrateV.getV14()/overlimit.getUharm14();
                    double v15 = dayHarmrateV.getV15()/overlimit.getUharm15();
                    double v16 = dayHarmrateV.getV16()/overlimit.getUharm16();
                    double v17 = dayHarmrateV.getV17()/overlimit.getUharm17();
                    double v18 = dayHarmrateV.getV18()/overlimit.getUharm18();
                    double v19 = dayHarmrateV.getV19()/overlimit.getUharm19();
                    double v20 = dayHarmrateV.getV20()/overlimit.getUharm20();
                    double v21 = dayHarmrateV.getV21()/overlimit.getUharm21();
                    double v22 = dayHarmrateV.getV22()/overlimit.getUharm22();
                    double v23 = dayHarmrateV.getV23()/overlimit.getUharm23();
                    double v24 = dayHarmrateV.getV24()/overlimit.getUharm24();
                    double v25 = dayHarmrateV.getV25()/overlimit.getUharm25();
                    data = Stream.of(v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,v17,v18,v19,v20,v21,v22,v23,v24,v25).collect(Collectors.toList());
                    double result = data.stream().max(Comparator.comparing(Double::doubleValue)).get();
                    publicDTO = new PublicDTO();
                    publicDTO.setId(dayHarmrateV.getLineId());
                    publicDTO.setData(result);
                    lineData.add(publicDTO);
                }
            }
        }
        Comparator<PublicDTO> comparator = Comparator.comparing(PublicDTO::getData);
        return lineData.stream().collect(Collectors.groupingBy(PublicDTO::getId,Collectors.reducing(BinaryOperator.maxBy(comparator))));
    }

    /**
     * 谐波电流 -> 各次谐波电流（2~25次）
     * 各监测点最新的A、B、C三相数据
     */
    private Map<String, Optional<PublicDTO>> getIharm(){
        String sql = "SELECT * FROM day_i where value_type = 'CP95' and (phasic_type = 'A' or phasic_type = 'B' or phasic_type = 'C') group by line_id order by time desc limit 3";
        QueryResult sqlResult = influxDbUtils.query(sql);
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        List<Double> data;
        PublicDTO publicDTO;
        List<PublicDTO> lineData = new ArrayList<>();
        List<DayI> list = resultMapper.toPOJO(sqlResult, DayI.class);
        List<Overlimit> overLimitList = getAllLinesLimitData();
        for (DayI dayI : list) {
            for (Overlimit overlimit : overLimitList) {
                if (Objects.equals(dayI.getLineId(),overlimit.getId())){
                    double v2 = dayI.getI2()/overlimit.getIharm2();
                    double v3 = dayI.getI3()/overlimit.getIharm3();
                    double v4 = dayI.getI4()/overlimit.getIharm4();
                    double v5 = dayI.getI5()/overlimit.getIharm5();
                    double v6 = dayI.getI6()/overlimit.getIharm6();
                    double v7 = dayI.getI7()/overlimit.getIharm7();
                    double v8 = dayI.getI8()/overlimit.getIharm8();
                    double v9 = dayI.getI9()/overlimit.getIharm9();
                    double v10 = dayI.getI10()/overlimit.getIharm10();
                    double v11 = dayI.getI11()/overlimit.getIharm11();
                    double v12 = dayI.getI12()/overlimit.getIharm12();
                    double v13 = dayI.getI13()/overlimit.getIharm13();
                    double v14 = dayI.getI14()/overlimit.getIharm14();
                    double v15 = dayI.getI15()/overlimit.getIharm15();
                    double v16 = dayI.getI16()/overlimit.getIharm16();
                    double v17 = dayI.getI17()/overlimit.getIharm17();
                    double v18 = dayI.getI18()/overlimit.getIharm18();
                    double v19 = dayI.getI19()/overlimit.getIharm19();
                    double v20 = dayI.getI20()/overlimit.getIharm20();
                    double v21 = dayI.getI21()/overlimit.getIharm21();
                    double v22 = dayI.getI22()/overlimit.getIharm22();
                    double v23 = dayI.getI23()/overlimit.getIharm23();
                    double v24 = dayI.getI24()/overlimit.getIharm24();
                    double v25 = dayI.getI25()/overlimit.getIharm25();
                    data = Stream.of(v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,v17,v18,v19,v20,v21,v22,v23,v24,v25).collect(Collectors.toList());
                    double result = data.stream().max(Comparator.comparing(Double::doubleValue)).get();
                    publicDTO = new PublicDTO();
                    publicDTO.setId(dayI.getLineId());
                    publicDTO.setData(result);
                    lineData.add(publicDTO);
                }
            }
        }
        Comparator<PublicDTO> comparator = Comparator.comparing(PublicDTO::getData);
        return lineData.stream().collect(Collectors.groupingBy(PublicDTO::getId,Collectors.reducing(BinaryOperator.maxBy(comparator))));
    }

    /**
     * 频率偏差 -> 绝对值
     * 各监测点最新的T相数据
     */
    private Map<String, Optional<PublicDTO>> getFreq(){
        String sql = "SELECT line_id,abs(freq_dev) AS freq_dev FROM day_v where phasic_type = 'T' and (value_type = 'MIN' or value_type = 'MAX') group by line_id order by time desc limit 2";
        QueryResult sqlResult = influxDbUtils.query(sql);
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        List<Double> data;
        PublicDTO publicDTO;
        List<PublicDTO> lineData = new ArrayList<>();
        List<DayV> list = resultMapper.toPOJO(sqlResult, DayV.class);
        List<Overlimit> overLimitList = getAllLinesLimitData();
        for (DayV dayV : list) {
            for (Overlimit overlimit : overLimitList) {
                if (Objects.equals(dayV.getLineId(),overlimit.getId())){
                    double freqDev = dayV.getFreqDev()/overlimit.getFreqDev();
                    data = Stream.of(freqDev).collect(Collectors.toList());
                    double result = data.stream().max(Comparator.comparing(Double::doubleValue)).get();
                    publicDTO = new PublicDTO();
                    publicDTO.setId(dayV.getLineId());
                    publicDTO.setData(result);
                    lineData.add(publicDTO);
                }
            }
        }
        Comparator<PublicDTO> comparator = Comparator.comparing(PublicDTO::getData);
        return lineData.stream().collect(Collectors.groupingBy(PublicDTO::getId,Collectors.reducing(BinaryOperator.maxBy(comparator))));
    }

    /**
     * 电压偏差 -> 绝对值
     * 各监测点最新的A、B、C三相数据
     */
    private Map<String, Optional<PublicDTO>> getDev(){
        String sql = "SELECT line_id,vu_dev,vl_dev,value_type FROM day_v where (phasic_type = 'A' or phasic_type = 'B' or phasic_type = 'C') and (value_type = 'MIN' or value_type = 'MAX') group by line_id order by time desc limit 6";
        QueryResult sqlResult = influxDbUtils.query(sql);
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        List<Double> data;
        PublicDTO publicDTO;
        List<PublicDTO> lineData = new ArrayList<>();
        List<DayV> list = resultMapper.toPOJO(sqlResult, DayV.class);
        List<Overlimit> overLimitList = getAllLinesLimitData();
        for (DayV dayV : list) {
            for (Overlimit overlimit : overLimitList) {
                if (Objects.equals(dayV.getLineId(),overlimit.getId())){
                    double vlDev = Math.abs(dayV.getVlDev()/overlimit.getUvoltageDev());
                    double vuDev = Math.abs(dayV.getVuDev()/overlimit.getVoltageDev());
                    data = Stream.of(vuDev,vlDev).collect(Collectors.toList());
                    double result = data.stream().max(Comparator.comparing(Double::doubleValue)).get();
                    publicDTO = new PublicDTO();
                    publicDTO.setId(dayV.getLineId());
                    publicDTO.setData(result);
                    lineData.add(publicDTO);
                }
            }
        }
        Comparator<PublicDTO> comparator = Comparator.comparing(PublicDTO::getData);
        return lineData.stream().collect(Collectors.groupingBy(PublicDTO::getId,Collectors.reducing(BinaryOperator.maxBy(comparator))));
    }

    /**
     * 三相电压不平衡度
     * 各监测点最新的T相数据
     */
    private Map<String, Optional<PublicDTO>> getUbalance(){
        String sql = "SELECT line_id,v_unbalance,value_type FROM day_v where phasic_type = 'T' and (value_type = 'CP95' or value_type = 'MAX') group by line_id order by time desc limit 2";
        QueryResult sqlResult = influxDbUtils.query(sql);
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        List<Double> data;
        PublicDTO publicDTO;
        List<PublicDTO> lineData = new ArrayList<>();
        List<DayV> list = resultMapper.toPOJO(sqlResult, DayV.class);
        List<Overlimit> overLimitList = getAllLinesLimitData();
        for (DayV dayV : list) {
            for (Overlimit overlimit : overLimitList) {
                if (Objects.equals(dayV.getLineId(),overlimit.getId())){
                    double vUnbalance = Math.abs(dayV.getVUnbalance()/overlimit.getUbalance());
                    data = Stream.of(vUnbalance).collect(Collectors.toList());
                    double result = data.stream().max(Comparator.comparing(Double::doubleValue)).get();
                    publicDTO = new PublicDTO();
                    publicDTO.setId(dayV.getLineId());
                    publicDTO.setData(result);
                    lineData.add(publicDTO);
                }
            }
        }
        Comparator<PublicDTO> comparator = Comparator.comparing(PublicDTO::getData);
        return lineData.stream().collect(Collectors.groupingBy(PublicDTO::getId,Collectors.reducing(BinaryOperator.maxBy(comparator))));
    }

    /**
     * 负序电流
     * 各监测点最新的T相数据
     */
    private Map<String, Optional<PublicDTO>> getIneg(){
        String sql = "SELECT line_id,i_neg,value_type FROM day_i where phasic_type = 'T' and (value_type = 'CP95' or value_type = 'MAX') group by line_id order by time desc limit 2";
        QueryResult sqlResult = influxDbUtils.query(sql);
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        List<Double> data;
        PublicDTO publicDTO;
        List<PublicDTO> lineData = new ArrayList<>();
        List<DayI> list = resultMapper.toPOJO(sqlResult, DayI.class);
        List<Overlimit> overLimitList = getAllLinesLimitData();
        for (DayI dayI : list) {
            for (Overlimit overlimit : overLimitList) {
                if (Objects.equals(dayI.getLineId(),overlimit.getId())){
                    double iNeg = Math.abs(dayI.getINeg()/overlimit.getINeg());
                    data = Stream.of(iNeg).collect(Collectors.toList());
                    double result = data.stream().max(Comparator.comparing(Double::doubleValue)).get();
                    publicDTO = new PublicDTO();
                    publicDTO.setId(dayI.getLineId());
                    publicDTO.setData(result);
                    lineData.add(publicDTO);
                }
            }
        }
        Comparator<PublicDTO> comparator = Comparator.comparing(PublicDTO::getData);
        return lineData.stream().collect(Collectors.groupingBy(PublicDTO::getId,Collectors.reducing(BinaryOperator.maxBy(comparator))));
    }

    /**
     * 间谐波电压含有率
     * 各监测点最新的A、B、C三相数据
     */
    private Map<String, Optional<PublicDTO>> getInuharm(){
        String sql = "SELECT * FROM day_inharm_v where (phasic_type = 'A' or phasic_type = 'B' or phasic_type = 'C') and value_type = 'CP95' group by line_id order by time desc limit 3";
        QueryResult sqlResult = influxDbUtils.query(sql);
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        List<Double> data;
        PublicDTO publicDTO;
        List<PublicDTO> lineData = new ArrayList<>();
        List<DayInharmV> list = resultMapper.toPOJO(sqlResult, DayInharmV.class);
        List<Overlimit> overLimitList = getAllLinesLimitData();
        for (DayInharmV dayInharmV : list) {
            for (Overlimit overlimit : overLimitList) {
                if (Objects.equals(dayInharmV.getLineId(),overlimit.getId())){
                    double v1 = Math.abs(dayInharmV.getV1()/overlimit.getInuharm1());
                    double v2 = Math.abs(dayInharmV.getV2()/overlimit.getInuharm2());
                    double v3 = Math.abs(dayInharmV.getV3()/overlimit.getInuharm3());
                    double v4 = Math.abs(dayInharmV.getV4()/overlimit.getInuharm4());
                    double v5 = Math.abs(dayInharmV.getV5()/overlimit.getInuharm5());
                    double v6 = Math.abs(dayInharmV.getV6()/overlimit.getInuharm6());
                    double v7 = Math.abs(dayInharmV.getV7()/overlimit.getInuharm7());
                    double v8 = Math.abs(dayInharmV.getV8()/overlimit.getInuharm8());
                    double v9 = Math.abs(dayInharmV.getV9()/overlimit.getInuharm9());
                    double v10 = Math.abs(dayInharmV.getV10()/overlimit.getInuharm10());
                    double v11 = Math.abs(dayInharmV.getV11()/overlimit.getInuharm11());
                    double v12 = Math.abs(dayInharmV.getV12()/overlimit.getInuharm12());
                    double v13 = Math.abs(dayInharmV.getV13()/overlimit.getInuharm13());
                    double v14 = Math.abs(dayInharmV.getV14()/overlimit.getInuharm14());
                    double v15 = Math.abs(dayInharmV.getV15()/overlimit.getInuharm15());
                    double v16 = Math.abs(dayInharmV.getV16()/overlimit.getInuharm16());
                    data = Stream.of(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16).collect(Collectors.toList());
                    double result = data.stream().max(Comparator.comparing(Double::doubleValue)).get();
                    publicDTO = new PublicDTO();
                    publicDTO.setId(dayInharmV.getLineId());
                    publicDTO.setData(result);
                    lineData.add(publicDTO);
                }
            }
        }
        Comparator<PublicDTO> comparator = Comparator.comparing(PublicDTO::getData);
        return lineData.stream().collect(Collectors.groupingBy(PublicDTO::getId,Collectors.reducing(BinaryOperator.maxBy(comparator))));
    }

    /**
     * 长时电压闪变
     * 各监测点最新的A、B、C三相数据
     */
    private Map<String, Optional<PublicDTO>> getFlicker(){
        String sql = "SELECT * FROM day_plt where (phasic_type = 'A' or phasic_type = 'B' or phasic_type = 'C') and value_type = 'CP95' group by line_id order by time desc limit 3";
        QueryResult sqlResult = influxDbUtils.query(sql);
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        List<Double> data;
        PublicDTO publicDTO;
        List<PublicDTO> lineData = new ArrayList<>();
        List<DayPlt> list = resultMapper.toPOJO(sqlResult, DayPlt.class);
        List<Overlimit> overLimitList = getAllLinesLimitData();
        for (DayPlt dayPlt : list) {
            for (Overlimit overlimit : overLimitList) {
                if (Objects.equals(dayPlt.getLineId(),overlimit.getId())){
                    double plt = Math.abs(dayPlt.getPlt()/overlimit.getFlicker());
                    data = Stream.of(plt).collect(Collectors.toList());
                    double result = data.stream().max(Comparator.comparing(Double::doubleValue)).get();
                    publicDTO = new PublicDTO();
                    publicDTO.setId(dayPlt.getLineId());
                    publicDTO.setData(result);
                    lineData.add(publicDTO);
                }
            }
        }
        Comparator<PublicDTO> comparator = Comparator.comparing(PublicDTO::getData);
        return lineData.stream().collect(Collectors.groupingBy(PublicDTO::getId,Collectors.reducing(BinaryOperator.maxBy(comparator))));
    }


    /**
     * 生成谐波污区图污染指标表
     */
    private void createMeasurement(List<PollutionDTO> list, long time){
        List<String> records = new ArrayList<String>();
        list.forEach(item->{
            Map<String, String> tags = new HashMap<>();
            Map<String, Object> fields = new HashMap<>();
            tags.put("line_id",item.getId());
            fields.put("freq",item.getData1());
            fields.put("freq_dev",item.getData2());
            fields.put("unbalance",item.getData3());
            fields.put("ineg",item.getData4());
            fields.put("harmonic_v",item.getData5());
            fields.put("harmonic_i",item.getData6());
            fields.put("inuharm",item.getData7());
            fields.put("flicker",item.getData8());
            Point point = influxDbUtils.pointBuilder("harmonic_pollution", time, TimeUnit.MILLISECONDS,tags, fields);
            BatchPoints batchPoints = BatchPoints.database(DATABASE).tag("line_id", item.getId()).retentionPolicy("").consistency(InfluxDB.ConsistencyLevel.ALL).build();
            batchPoints.point(point);
            records.add(batchPoints.lineProtocol());
        });
        influxDbUtils.batchInsert(DATABASE,"", InfluxDB.ConsistencyLevel.ALL, records);
    }
}
