package com.njcn.harmonic.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.njcn.common.utils.PubUtils;
import com.njcn.device.api.LineFeignClient;
import com.njcn.device.pojo.po.Overlimit;
import com.njcn.device.pojo.vo.LineDetailDataVO;
import com.njcn.event.api.EventDetailFeignClient;
import com.njcn.event.pojo.po.EventDetail;
import com.njcn.harmonic.constant.Param;
import com.njcn.harmonic.pojo.param.HistoryParam;
import com.njcn.harmonic.pojo.param.NormHistoryParam;
import com.njcn.harmonic.pojo.vo.EventDetailVO;
import com.njcn.harmonic.pojo.vo.HistoryDataResultVO;
import com.njcn.harmonic.pojo.vo.QueryResultLimitVO;
import com.njcn.harmonic.service.HistoryResultService;
import com.njcn.influxdb.utils.InfluxDbUtils;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.influxdb.dto.QueryResult;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author denghuajun
 * @date 2022/3/14
 */
@Service
@AllArgsConstructor
public class HistoryResultServiceImpl implements HistoryResultService {

    private final InfluxDbUtils influxDbUtils;

    private final LineFeignClient lineFeignClient;

    private final EventDetailFeignClient eventDetailFeignClient;

    @Override
    public List<HistoryDataResultVO> getHistoryResult(HistoryParam historyParam) {
        List<HistoryDataResultVO> historyDataResultVOList = new ArrayList<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //获取监测点
        String[] points = historyParam.getLineId();
        Integer number = 0;
        for (int i = 0; i < points.length; i++) {
            HistoryDataResultVO historyDataResultVO;
            List<EventDetail> eventDetailList = eventDetailFeignClient.getEventDetailData(points[i],historyParam.getSearchBeginTime(),historyParam.getSearchEndTime()).getData();
            List<EventDetailVO> eventDetailVOList = new ArrayList<>();
            if (!eventDetailList.isEmpty()) {
                for (EventDetail eventdetail : eventDetailList) {
                    EventDetailVO eventDetailVO = new EventDetailVO();
                    eventDetailVO.setId(eventdetail.getId());
                    eventDetailVO.setTime(formatter.format(eventdetail.getTimeId()));
                    eventDetailVOList.add(eventDetailVO);
                }
            }
            //获取指标
            String[] contions = historyParam.getCondition();
            for (int j = 0; j < contions.length; j++) {
                if ("40".equals(contions[j]) || "41".equals(contions[j]) || "42".equals(contions[j]) || "43".equals(contions[j])
                        || "44".equals(contions[j]) || "45".equals(contions[j]) || "50".equals(contions[j]) || "51".equals(contions[j])
                        || "52".equals(contions[j])) {
                    number = historyParam.getHarmonic();
                }
                if ("46".equals(contions[j]) || "47".equals(contions[j]) || "48".equals(contions[j]) || "49".equals(contions[j])) {
                    number = historyParam.getInHarmonic();
                }
                historyDataResultVO = getCondition(historyParam.getSearchBeginTime(), historyParam.getSearchEndTime(), points[i], contions[j], number, historyParam.getValueType(), historyParam.getPtType());
                historyDataResultVOList.add(historyDataResultVO);
                if (points.length == 1 && j == 0) {
                    historyDataResultVO.setEventDetail(eventDetailVOList);
                } else if (points.length > 1) {
                    historyDataResultVO.setEventDetail(eventDetailVOList);
                }
            }
        }
        return historyDataResultVOList;
    }

    @Override
    public List<HistoryDataResultVO> getHistoryLineData(NormHistoryParam normHistoryParam) {
        List<HistoryDataResultVO> historyDataResultVOList = new ArrayList<>();
        HistoryDataResultVO historyDataResultVO = getNormCondition(normHistoryParam);
        historyDataResultVOList.add(historyDataResultVO);
        return historyDataResultVOList;
    }

    /**
     * influxDB相关操作
     * 查询稳态数据分析
     */
    @SneakyThrows
    private HistoryDataResultVO getCondition(String startTime, String endTime, String lineId, String contion, Integer number, Integer valueType, Integer ptType) {
        HistoryDataResultVO historyDataResultVO = new HistoryDataResultVO();
        QueryResultLimitVO queryResultLimitVO = getQueryResult(startTime, endTime, lineId, contion, number, valueType, ptType);
        QueryResult queryResult = queryResultLimitVO.getQueryResult();
        BeanUtil.copyProperties(queryResultLimitVO, historyDataResultVO);
        List<QueryResult.Series> list = queryResult.getResults().get(0).getSeries();
        List<Date> time = new ArrayList<>();
        List<Float> aValue = new ArrayList<>();
        List<Float> bValue = new ArrayList<>();
        List<Float> cValue = new ArrayList<>();
        List<Float> fValue = new ArrayList<>();
        List<List<Object>> objectListData = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            if (queryResult.getResults().size() == 1) {
                List<List<Object>> listData = queryResult.getResults().get(0).getSeries().get(0).getValues();
                for (int i = 0; i < listData.size(); i++) {
                    List<Object> objectList = listData.get(i);
                    DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
                    TimeZone tx = TimeZone.getTimeZone("Asia/Kolkata");
                    formatter.setTimeZone(tx);
                    Date d = formatter.parse(objectList.get(0).toString());
                    time.add(d);
                    fValue.add(BigDecimal.valueOf(Float.parseFloat(objectList.get(1).toString())).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue());
                }
                for (int i = 0; i < time.size(); i++) {
                    List<Object> objects = new ArrayList<>();
                    objects.add(time.get(i));
                    objects.add(fValue.get(i));
                    objectListData.add(objects);
                }
                historyDataResultVO.setTopLimit(queryResultLimitVO.getTopLimit());
                historyDataResultVO.setLowerLimit(queryResultLimitVO.getLowerLimit());
                historyDataResultVO.setMinValue(Collections.min(fValue));
                historyDataResultVO.setValue(objectListData);

            } else {
                for (int i = 0; i < queryResult.getResults().size(); i++) {
                    List<QueryResult.Series> listData = queryResult.getResults().get(i).getSeries();
                    List<List<Object>> values = listData.get(0).getValues();
                    for (int j = 0; j < values.size(); j++) {
                        List<Object> objectList = values.get(j);
                        if (i == 0) {
                            DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
                            TimeZone tx = TimeZone.getTimeZone("Asia/Kolkata");
                            formatter.setTimeZone(tx);
                            Date d = formatter.parse(objectList.get(0).toString());
                            time.add(d);
                            aValue.add(BigDecimal.valueOf(Float.parseFloat(objectList.get(1).toString())).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue());
                        } else if (i == 1) {
                            bValue.add(BigDecimal.valueOf(Float.parseFloat(objectList.get(1).toString())).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue());
                        } else {
                            cValue.add(BigDecimal.valueOf(Float.parseFloat(objectList.get(1).toString())).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue());
                        }
                    }
                }
                for (int i = 0; i < time.size(); i++) {
                    List<Object> objects = new ArrayList<>();
                    objects.add(time.get(i));
                    objects.add(aValue.get(i));
                    objects.add(bValue.get(i));
                    objects.add(cValue.get(i));
                    objectListData.add(objects);
                }
                Float aValueMin = Collections.min(aValue);
                Float bValueMin = Collections.min(bValue);
                Float cValueMin = Collections.min(cValue);

                historyDataResultVO.setMinValue((aValueMin < bValueMin) ? ((aValueMin < cValueMin) ? aValueMin : cValueMin) : ((bValueMin < cValueMin) ? bValueMin : cValueMin));
                historyDataResultVO.setTopLimit(queryResultLimitVO.getTopLimit());
                historyDataResultVO.setLowerLimit(queryResultLimitVO.getLowerLimit());
                historyDataResultVO.setValue(objectListData);
            }

        } else {
            return historyDataResultVO;
        }
        return historyDataResultVO;
    }

    private QueryResultLimitVO getQueryResult(String startTime, String endTime, String lineList, String contion, Integer number, Integer valueType, Integer ptType) {
        QueryResultLimitVO queryResultLimitVO = new QueryResultLimitVO();
        QueryResult queryResult;
        if (!lineList.isEmpty()) {
            Float topLimit = 0f;
            Float lowerLimit = 0f;
            //获取限值
            Overlimit overlimit = lineFeignClient.getOverLimitData(lineList).getData();
            //获取监测点信息
            LineDetailDataVO lineDetailDataVO = lineFeignClient.getLineDetailData(lineList).getData();
            //组装sql语句
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(Param.TIME + " >= '").append(startTime).append(Param.START_TIME).append("' and ").append(Param.TIME).append(" <= '").append(endTime).append(Param.END_TIME).append("' and (");
            //sql语句
            stringBuilder.append(Param.LINE_ID + "='").append(lineList).append("')");
            String valueTypeName = "";
            switch (valueType) {
                case 1:
                    valueTypeName = "AVG";
                    break;
                case 2:
                    valueTypeName = "MAX";
                    break;
                case 3:
                    valueTypeName = "MIN";
                    break;
                case 4:
                    valueTypeName = "CP95";
                    break;
                default:
                    break;
            }
            stringBuilder.append(" and ").append(Param.VALUETYPE + "='").append(valueTypeName).append("'");
            String sql = "";
            List<String> phasicType = new ArrayList<>();
            List<String> unit = new ArrayList<>();
            String targetName = "";
            switch (Integer.parseInt(contion)) {
                case 10:
                    //相电压有效值
                    sql = "SELECT time as time, rms as aValue FROM data_v WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc";
                    phasicType.add("A相");
                    phasicType.add("B相");
                    phasicType.add("C相");
                    unit.add("kV");
                    targetName = "相电压有效值";
                    break;
                case 11:
                    //线电压有效值
                    sql = "SELECT time as time, rms_lvr as aValue FROM data_v WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    phasicType.add("AB相");
                    phasicType.add("BC相");
                    phasicType.add("CA相");
                    unit.add("kV");
                    targetName = "线电压有效值";
                    break;
                case 12:
                    //电压偏差
                    sql = "SELECT time as time, vu_dev as aValue FROM data_v WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    topLimit = overlimit.getVoltageDev();
                    lowerLimit = overlimit.getUvoltageDev();
                    if (ptType == 0) {
                        phasicType.add("A相");
                        phasicType.add("B相");
                        phasicType.add("C相");
                    } else {
                        phasicType.add("AB相");
                        phasicType.add("BC相");
                        phasicType.add("CA相");
                    }
                    unit.add("%");
                    targetName = "电压偏差";
                    break;
                case 13:
                    //三相电压不平衡度
                    sql = "SELECT time as time, v_unbalance as aValue FROM data_v WHERE " + stringBuilder.toString() +
                            " and phasic_type ='T' order by time asc;";
                    topLimit = overlimit.getUbalance();
                    phasicType.add("三相电压不平衡度");
                    unit.add("%");
                    targetName = "三相电压不平衡度";
                    break;
                case 14:
                    //电压不平衡
                    sql = "SELECT time as time, v_zero as aValue FROM data_v WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    phasicType.add("零序电压");
                    phasicType.add("正序电压");
                    phasicType.add("负序电压");
                    unit.add("V");
                    unit.add("kV");
                    unit.add("V");
                    targetName = "电压不平衡";
                    break;
                case 15:
                    //电压总谐波畸变率
                    sql = "SELECT time as time, v_thd as aValue FROM data_v WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    topLimit = overlimit.getUaberrance();
                    if (ptType == 0) {
                        phasicType.add("A相");
                        phasicType.add("B相");
                        phasicType.add("C相");
                    } else {
                        phasicType.add("AB相");
                        phasicType.add("BC相");
                        phasicType.add("CA相");
                    }
                    unit.add("%");
                    targetName = "电压总谐波畸变率";
                    break;
                case 20:
                    //电流有效值
                    sql = "SELECT time as time, rms as aValue FROM data_i WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    phasicType.add("A相");
                    phasicType.add("B相");
                    phasicType.add("C相");
                    unit.add("A");
                    targetName = "电流有效值";
                    break;
                case 21:
                    //电流总畸变率
                    sql = "SELECT time as time, i_thd as aValue FROM data_i WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    phasicType.add("A相");
                    phasicType.add("B相");
                    phasicType.add("C相");
                    unit.add("%");
                    targetName = "电流总谐波畸变率";
                    break;
                case 22:
                    //负序电流
                    sql = "SELECT time as time, i_neg as aValue FROM data_i WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    topLimit = overlimit.getINeg();
                    phasicType.add("负序电流");
                    unit.add("A");
                    targetName = "负序电流";
                    break;
                case 30:
                    //频率 V9暂时代表Freq
                    sql = "SELECT time as time, freq as aValue FROM data_v WHERE " + stringBuilder.toString() +
                            " and phasic_type ='T' order by time asc;";
                    topLimit = 50 + overlimit.getFreqDev();
                    lowerLimit = 50 - overlimit.getFreqDev();
                    phasicType.add("频率");
                    unit.add("Hz");
                    targetName = "频率";
                    break;
                case 40:
                    //谐波电压含有率
                    sql = "SELECT time as time, v_" + number + " as aValue FROM data_harmrate_v WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    topLimit = PubUtils.getValueByMethod(overlimit, "getUharm", number);
                    if (ptType == 0) {
                        phasicType.add("A相");
                        phasicType.add("B相");
                        phasicType.add("C相");
                    } else {
                        phasicType.add("AB相");
                        phasicType.add("BC相");
                        phasicType.add("CA相");
                    }
                    unit.add("%");
                    targetName = "谐波电压含有率";
                    break;
                case 41:
                    //谐波电流含有率
                    sql = "SELECT time as time, i_" + number + " as aValue FROM data_harmrate_i WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    phasicType.add("A相");
                    phasicType.add("B相");
                    phasicType.add("C相");
                    unit.add("%");
                    targetName = "谐波电流含有率";
                    break;
                case 42:
                    //谐波电压幅值
                    sql = "SELECT time as time, v_" + number + " as aValue FROM data_v WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    if (ptType == 0) {
                        phasicType.add("A相");
                        phasicType.add("B相");
                        phasicType.add("C相");
                    } else {
                        phasicType.add("AB相");
                        phasicType.add("BC相");
                        phasicType.add("CA相");
                    }
                    if (number == 1) {
                        unit.add("kV");
                    } else {
                        unit.add("V");
                    }
                    targetName = "谐波电压幅值";
                    break;
                case 43:
                    //谐波电流幅值
                    sql = "SELECT time as time, i_" + number + " as aValue FROM data_i WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    topLimit = PubUtils.getValueByMethod(overlimit, "getIharm", number);
                    phasicType.add("A相");
                    phasicType.add("B相");
                    phasicType.add("C相");
                    unit.add("A");
                    targetName = "谐波电流幅值";
                    break;
                case 44:
                    //谐波电压相角
                    sql = "SELECT time as time, v_" + number + " as aValue FROM data_harmphasic_v WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    if (ptType == 0) {
                        phasicType.add("A相");
                        phasicType.add("B相");
                        phasicType.add("C相");
                    } else {
                        phasicType.add("AB相");
                        phasicType.add("BC相");
                        phasicType.add("CA相");
                    }
                    unit.add("°");
                    targetName = "谐波电压相角";
                    break;
                case 45:
                    //谐波电流相角
                    sql = "SELECT time as time, i_" + number + " as aValue FROM data_harmphasic_i WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    phasicType.add("A相");
                    phasicType.add("B相");
                    phasicType.add("C相");
                    unit.add("°");
                    targetName = "谐波电流相角";
                    break;
                case 46:
                    //间谐波电压含有率
                    sql = "SELECT time as time, v_" + number + " as aValue FROM data_inharmrate_v WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    topLimit = PubUtils.getValueByMethod(overlimit, "getInuharm", number);
                    if (ptType == 0) {
                        phasicType.add("A相");
                        phasicType.add("B相");
                        phasicType.add("C相");
                    } else {
                        phasicType.add("AB相");
                        phasicType.add("BC相");
                        phasicType.add("CA相");
                    }
                    unit.add("%");
                    targetName = "间谐波电压含有率";
                    break;
                case 47:
                    //间谐波电流含有率
                    sql = "SELECT time as time, i_" + number + " as aValue FROM data_inharmrate_i WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    phasicType.add("A相");
                    phasicType.add("B相");
                    phasicType.add("C相");
                    unit.add("%");
                    targetName = "间谐波电流含有率";
                    break;
                case 48:
                    //间谐波电压幅值
                    sql = "SELECT time as time, v_" + number + " as aValue FROM data_inharm_v WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    targetName = "间谐波电压幅值";
                    if (ptType == 0) {
                        phasicType.add("A相");
                        phasicType.add("B相");
                        phasicType.add("C相");
                    } else {
                        phasicType.add("AB相");
                        phasicType.add("BC相");
                        phasicType.add("CA相");
                    }
                    unit.add("kV");
                    break;
                case 49:
                    //间谐波电流幅值
                    sql = "SELECT time as time, i_" + number + " as aValue FROM data_inharm_i WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    phasicType.add("A相");
                    phasicType.add("B相");
                    phasicType.add("C相");
                    unit.add("A");
                    targetName = "间谐波电流幅值";
                    break;
                case 50:
                    //谐波有功功率
                    sql = "SELECT time as time, p_" + number + " as aValue FROM data_harmpower_p WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    phasicType.add("A相");
                    phasicType.add("B相");
                    phasicType.add("C相");
                    if (number == 1) {
                        unit.add("kW");
                    } else {
                        unit.add("W");
                    }
                    targetName = "谐波有功功率";
                    break;
                case 51:
                    //谐波无功功率
                    sql = "SELECT time as time, q_" + number + " as aValue FROM data_harmpower_q WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    phasicType.add("A相");
                    phasicType.add("B相");
                    phasicType.add("C相");
                    if (number == 1) {
                        unit.add("kVar");
                    } else {
                        unit.add("Var");
                    }
                    targetName = "谐波无功功率";
                    break;
                case 52:
                    //谐波视在功率
                    sql = "SELECT time as time, s_" + number + " as aValue FROM data_harmpower_s WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    phasicType.add("A相");
                    phasicType.add("B相");
                    phasicType.add("C相");
                    if (number == 1) {
                        unit.add("kVA");
                    } else {
                        unit.add("VA");
                    }
                    targetName = "谐波视在功率";
                    break;
                case 53:
                    //三相有功功率
                    sql = "SELECT time as time, p as aValue FROM data_harmpower_p WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    phasicType.add("A相");
                    phasicType.add("B相");
                    phasicType.add("C相");
                    unit.add("kW");
                    targetName = "三相有功功率";
                    break;
                case 54:
                    //三相无功功率
                    sql = "SELECT time as time, q as aValue FROM data_harmpower_q WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    phasicType.add("A相");
                    phasicType.add("B相");
                    phasicType.add("C相");
                    unit.add("kVar");
                    targetName = "三相无功功率";
                    break;
                case 55:
                    //三相视在功率
                    sql = "SELECT time as time, s as aValue FROM data_harmpower_s WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    phasicType.add("A相");
                    phasicType.add("B相");
                    phasicType.add("C相");
                    unit.add("kVA");
                    targetName = "三相视在功率";
                    break;
                case 56:
                    //三相总有功功率
                    sql = "SELECT time as time, p as aValue FROM data_harmpower_p WHERE " + stringBuilder.toString() +
                            " and phasic_type ='T' order by time asc;";
                    phasicType.add("三相总有功功率");
                    unit.add("kW");
                    targetName = "三相总有功功率";
                    break;
                case 57:
                    //三相总无功功率
                    sql = "SELECT time as time, q as aValue FROM data_harmpower_q WHERE " + stringBuilder.toString() +
                            " and phasic_type ='T' order by time asc;";
                    phasicType.add("三相总无功功率");
                    unit.add("kVar");
                    targetName = "三相总无功功率";
                    break;
                case 58:
                    //三相总视在功率
                    sql = "SELECT time as time, s as aValue FROM data_harmpower_s WHERE " + stringBuilder.toString() +
                            " and phasic_type ='T' order by time asc;";
                    phasicType.add("三相总视在功率");
                    unit.add("kVA");
                    targetName = "三相总视在功率";
                    break;
                case 59:
                    //视在功率因数
                    sql = "SELECT time as time, pf as aValue FROM data_harmpower_p WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    phasicType.add("A相");
                    phasicType.add("B相");
                    phasicType.add("C相");
                    targetName = "视在功率因数";
                    break;
                case 591:
                    //位移功率因数
                    sql = "SELECT time as time, df as aValue FROM data_harmpower_p WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    phasicType.add("A相");
                    phasicType.add("B相");
                    phasicType.add("C相");
                    targetName = "位移功率因数";
                    break;
                case 592:
                    //总视在功率因数
                    sql = "SELECT time as time, pf as aValue FROM data_harmpower_p WHERE " + stringBuilder.toString() +
                            " and phasic_type ='T' order by time asc;";
                    phasicType.add("总视在功率因数");
                    targetName = "总视在功率因数";
                    break;
                case 593:
                    //总位移功率因数
                    sql = "SELECT time as time, df as aValue FROM data_harmpower_p WHERE " + stringBuilder.toString() +
                            " and phasic_type ='T' order by time asc;";
                    phasicType.add("总位移功率因数");
                    targetName = "总位移功率因数";
                    break;
                case 61:
                    //长时闪变
                    sql = "SELECT time as time, plt as aValue FROM data_plt WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    if (ptType == 0) {
                        phasicType.add("A相");
                        phasicType.add("B相");
                        phasicType.add("C相");
                    } else {
                        phasicType.add("AB相");
                        phasicType.add("BC相");
                        phasicType.add("CA相");
                    }
                    topLimit = overlimit.getFlicker();
                    targetName = "长时闪变";
                    break;
                case 60:
                    //短时闪变
                    sql = "SELECT time as time, pst as aValue FROM data_flicker WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    topLimit = overlimit.getFlicker();
                    if (ptType == 0) {
                        phasicType.add("A相");
                        phasicType.add("B相");
                        phasicType.add("C相");
                    } else {
                        phasicType.add("AB相");
                        phasicType.add("BC相");
                        phasicType.add("CA相");
                    }
                    targetName = "短时闪变";
                    break;
                case 62:
                    //电压波动
                    sql = "SELECT time as time, fluc as aValue FROM data_fluc WHERE " + stringBuilder.toString() +
                            " and (phasic_type ='A' or phasic_type ='B' or phasic_type ='C') group by phasic_type order by time asc;";
                    if (ptType == 0) {
                        phasicType.add("A相");
                        phasicType.add("B相");
                        phasicType.add("C相");
                    } else {
                        phasicType.add("AB相");
                        phasicType.add("BC相");
                        phasicType.add("CA相");
                    }
                    targetName = "电压波动";
                    break;
                default:
                    break;
            }
            queryResult = influxDbUtils.query(sql);
            queryResultLimitVO.setQueryResult(queryResult);
            queryResultLimitVO.setTopLimit(topLimit);
            queryResultLimitVO.setLowerLimit(lowerLimit);
            queryResultLimitVO.setPhaiscType(phasicType);
            queryResultLimitVO.setUnit(unit);
            queryResultLimitVO.setLineName(lineDetailDataVO.getLineName());
            queryResultLimitVO.setHarmNum(number);
            queryResultLimitVO.setTargetName(targetName);
        } else {
            return queryResultLimitVO;
        }
        return queryResultLimitVO;
    }


    private QueryResultLimitVO getQueryNormDataResult(NormHistoryParam normHistoryParam) {
        QueryResultLimitVO queryResultLimitVO = new QueryResultLimitVO();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        QueryResult queryResult = null;
        if (!normHistoryParam.getLineId().isEmpty()) {
            Float topLimit = 0f;
            Float lowerLimit = 0f;
            String lineList = normHistoryParam.getLineId();
            String startTime = sdf.format(DateUtil.beginOfDay(DateUtil.parse(normHistoryParam.getSearchTime())));
            String endTime = sdf.format(DateUtil.endOfDay(DateUtil.parse(normHistoryParam.getSearchTime())));
            Integer valueType = normHistoryParam.getValueType();
            //获取限值
            Overlimit overlimit = lineFeignClient.getOverLimitData(lineList).getData();
            //获取监测点信息
            LineDetailDataVO lineDetailDataVO = lineFeignClient.getLineDetailData(lineList).getData();
            //组装sql语句
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(Param.TIME + " >= '").append(startTime).append("' and ").append(Param.TIME).append(" <= '").append(endTime).append("' and (");
            //sql语句
            stringBuilder.append(Param.LINE_ID + "='").append(lineList).append("')");
            String valueTypeName = "";
            String phasicType = "";
            switch (valueType) {
                case 1:
                    valueTypeName = "AVG";
                    break;
                case 2:
                    valueTypeName = "MAX";
                    break;
                case 3:
                    valueTypeName = "MIN";
                    break;
                case 4:
                    valueTypeName = "CP95";
                    break;
                default:
                    break;
            }
            if ("A".equals(normHistoryParam.getPhaseType()) || "AB".equals(normHistoryParam.getPhaseType())) {
                phasicType = "A";
            } else if ("B".equals(normHistoryParam.getPhaseType()) || "BC".equals(normHistoryParam.getPhaseType())) {
                phasicType = "B";
            } else if ("C".equals(normHistoryParam.getPhaseType()) || "CA".equals(normHistoryParam.getPhaseType())) {
                phasicType = "C";
            }
            stringBuilder.append(" and ").append(Param.VALUETYPE + "='").append(valueTypeName).append("'");
            stringBuilder.append(" and ").append("phasic_type ='").append(phasicType).append("'");
            String sql = "";
            List<String> unit = new ArrayList<>();
            Integer number = normHistoryParam.getNumber();
            String targetName = "";
            switch (Integer.parseInt(normHistoryParam.getTargetCode())) {
                case 12:
                    //电压偏差
                    sql = "SELECT time as time, vu_dev as aValue FROM data_v WHERE " + stringBuilder.toString() +
                            " order by time asc;";
                    topLimit = overlimit.getVoltageDev();
                    lowerLimit = overlimit.getUvoltageDev();
                    unit.add("%");
                    targetName = "电压偏差";
                    break;
                case 13:
                    //三相电压不平衡度
                    sql = "SELECT time as time, v_unbalance as aValue FROM data_v WHERE " + stringBuilder.toString() +
                            " order by time asc;";
                    topLimit = overlimit.getUbalance();
                    unit.add("%");
                    targetName = "三相电压不平衡度";
                    break;
                case 15:
                    //电压总谐波畸变率
                    sql = "SELECT time as time, v_thd as aValue FROM data_v WHERE " + stringBuilder.toString() +
                            " order by time asc;";
                    topLimit = overlimit.getUaberrance();
                    unit.add("%");
                    targetName = "电压总谐波畸变率";
                    break;
                case 22:
                    //负序电流
                    sql = "SELECT time as time, i_neg as aValue FROM data_i WHERE " + stringBuilder.toString() +
                            " order by time asc;";
                    topLimit = overlimit.getINeg();
                    unit.add("A");
                    targetName = "负序电流";
                    break;
                case 30:
                    //频率 V9暂时代表Freq
                    sql = "SELECT time as time, freq as aValue FROM data_v WHERE " + stringBuilder.toString() +
                            " and phasic_type ='T' order by time asc;";
                    topLimit = 50 + overlimit.getFreqDev();
                    lowerLimit = 50 - overlimit.getFreqDev();
                    unit.add("Hz");
                    targetName = "频率";
                    break;
                case 40:
                    //谐波电压含有率
                    sql = "SELECT time as time, v_" + number + " as aValue FROM data_harmrate_v WHERE " + stringBuilder.toString() +
                            " and phasic_type ='A' order by time asc;" +
                            "SELECT time as time, v_" + number + " as bValue FROM data_harmrate_v WHERE " + stringBuilder.toString() +
                            " and phasic_type ='B' order by time asc;" +
                            "SELECT time as time, v_" + number + " as cValue FROM data_harmrate_v WHERE " + stringBuilder.toString() +
                            " and phasic_type ='C' order by time asc;";
                    topLimit = PubUtils.getValueByMethod(overlimit, "getUharm", number);
                    unit.add("%");
                    targetName = "谐波电压含有率";
                    break;
                case 41:
                    //谐波电流含有率
                    sql = "SELECT time as time, i_" + number + " as aValue FROM data_harmrate_i WHERE " + stringBuilder.toString() +
                            " and phasic_type ='A' order by time asc;" +
                            "SELECT time as time, i_" + number + " as bValue FROM data_harmrate_i WHERE " + stringBuilder.toString() +
                            " and phasic_type ='B' order by time asc;" +
                            "SELECT time as time, i_" + number + " as cValue FROM data_harmrate_i WHERE " + stringBuilder.toString() +
                            " and phasic_type ='C' order by time asc;";
                    unit.add("%");
                    targetName = "谐波电流含有率";
                    break;
                case 43:
                    //谐波电流幅值
                    sql = "SELECT time as time, i_" + number + " as aValue FROM data_i WHERE " + stringBuilder.toString() +
                            " and phasic_type ='A' order by time asc;" +
                            "SELECT time as time, i_" + number + " as bValue FROM data_i WHERE " + stringBuilder.toString() +
                            " and phasic_type ='B' order by time asc;" +
                            "SELECT time as time, i_" + number + " as cValue FROM data_i WHERE " + stringBuilder.toString() +
                            " and phasic_type ='C' order by time asc;";
                    topLimit = PubUtils.getValueByMethod(overlimit, "getIharm", number);
                    unit.add("A");
                    targetName = "谐波电流幅值";
                    break;

                case 46:
                    //间谐波电压含有率
                    sql = "SELECT time as time, v_" + number + " as aValue FROM data_inharmrate_v WHERE " + stringBuilder.toString() +
                            " and phasic_type ='A' order by time asc;" +
                            "SELECT time as time, v_" + number + " as bValue FROM data_inharmrate_v WHERE " + stringBuilder.toString() +
                            " and phasic_type ='B' order by time asc;" +
                            "SELECT time as time, v_" + number + " as cValue FROM data_inharmrate_v WHERE " + stringBuilder.toString() +
                            " and phasic_type ='C' order by time asc;";
                    topLimit = PubUtils.getValueByMethod(overlimit, "getInuharm", number);
                    unit.add("%");
                    targetName = "间谐波电压含有率";
                    break;
                case 61:
                    //长时闪变
                    sql = "SELECT time as time, plt as aValue FROM data_plt WHERE " + stringBuilder.toString() +
                            " and phasic_type ='A' order by time asc;" +
                            "SELECT time as time, plt as bValue FROM data_plt WHERE " + stringBuilder.toString() +
                            " and phasic_type ='B' order by time asc;" +
                            "SELECT time as time, plt as cValue FROM data_plt WHERE " + stringBuilder.toString() +
                            " and phasic_type ='C' order by time asc;";
                    targetName = "长时闪变";
                    topLimit = overlimit.getFlicker();
                    break;
                default:
                    break;
            }
            queryResult = influxDbUtils.query(sql);
            queryResultLimitVO.setQueryResult(queryResult);
            queryResultLimitVO.setTopLimit(topLimit);
            queryResultLimitVO.setLowerLimit(lowerLimit);
            queryResultLimitVO.setPhaiscType(Collections.singletonList(phasicType));
            queryResultLimitVO.setUnit(unit);
            queryResultLimitVO.setLineName(lineDetailDataVO.getLineName());
            queryResultLimitVO.setHarmNum(number);
            queryResultLimitVO.setTargetName(targetName);
        } else {
            return queryResultLimitVO;
        }
        return queryResultLimitVO;
    }

    /**
     * influxDB相关操作
     * 查询稳态数据分析
     */
    @SneakyThrows
    private HistoryDataResultVO getNormCondition(NormHistoryParam normHistoryParam) {
        HistoryDataResultVO historyDataResultVO = new HistoryDataResultVO();
        QueryResultLimitVO queryResultLimitVO = getQueryNormDataResult(normHistoryParam);
        QueryResult queryResult = queryResultLimitVO.getQueryResult();
        BeanUtil.copyProperties(queryResultLimitVO, historyDataResultVO);
        List<QueryResult.Series> list = queryResult.getResults().get(0).getSeries();
        List<Date> time = new ArrayList<>();
        List<Float> fValue = new ArrayList<>();
        List<List<Object>> objectListData = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            List<List<Object>> listData = queryResult.getResults().get(0).getSeries().get(0).getValues();
            for (int i = 0; i < listData.size(); i++) {
                List<Object> objectList = listData.get(i);
                DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
                TimeZone tx = TimeZone.getTimeZone("Asia/Kolkata");
                formatter.setTimeZone(tx);
                Date d = formatter.parse(objectList.get(0).toString());
                time.add(d);
                fValue.add(BigDecimal.valueOf(Float.parseFloat(objectList.get(1).toString())).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue());
            }
            for (int i = 0; i < time.size(); i++) {
                List<Object> objects = new ArrayList<>();
                objects.add(time.get(i));
                objects.add(fValue.get(i));
                objectListData.add(objects);
            }
            historyDataResultVO.setTopLimit(queryResultLimitVO.getTopLimit());
            historyDataResultVO.setLowerLimit(queryResultLimitVO.getLowerLimit());
            historyDataResultVO.setValue(objectListData);
        } else {
            return historyDataResultVO;
        }
        return historyDataResultVO;
    }
}
