package com.njcn.harmonic.service.impl;

import com.njcn.device.api.GeneralDeviceInfoClient;
import com.njcn.device.pojo.dto.GeneralDeviceDTO;
import com.njcn.device.pojo.param.DeviceInfoParam;
import com.njcn.harmonic.constant.Param;
import com.njcn.harmonic.pojo.dto.ComAssessDTO;
import com.njcn.harmonic.pojo.po.PQSComAssesPO;
import com.njcn.harmonic.pojo.vo.ComAssessVO;
import com.njcn.harmonic.service.ComAssessService;
import com.njcn.harmonic.utils.HarmonicComAssesUtil;
import com.njcn.influxdb.utils.InfluxDbUtils;
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.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
 * @version 1.0.0
 * @author: chenchao
 * @date: 2022/04/21 10:03
 */
@Service
@AllArgsConstructor
public class ComAssessServiceImpl implements ComAssessService {

    private final GeneralDeviceInfoClient generalDeviceInfoClient;

    private final InfluxDbUtils influxDbUtils;

    private final HarmonicComAssesUtil comAssesUtil;

    @Override
    public List<ComAssessVO> getComAccessData(DeviceInfoParam.BusinessParam comAccessParam) {
        List<ComAssessVO> comAssessVOList = new ArrayList<>();
        List<ComAssessDTO> comAssessDTOS = new ArrayList<>();
        //按照条件获取实际运行终端综合信息
        List<GeneralDeviceDTO> deviceDataList = generalDeviceInfoClient.getPracticalRunDeviceInfo(comAccessParam).getData();
        if (!CollectionUtils.isEmpty(deviceDataList)) {
            for (GeneralDeviceDTO generalDeviceDTO: deviceDataList){
                List<String> lineIndexes = generalDeviceDTO.getLineIndexes();
                ComAssessVO comAssessVO = new ComAssessVO();
                comAssessVO.setName(generalDeviceDTO.getName());
                comAssessVO.setMonitors(lineIndexes.size());
                if (!CollectionUtils.isEmpty(lineIndexes)) {
                    List<PQSComAssesPO> pqsComAssesPOS = getComAccessData(lineIndexes, comAccessParam.getSearchBeginTime(), comAccessParam.getSearchEndTime());
                    setResults(pqsComAssesPOS,comAssessDTOS);

                    float allComAss = comAssesUtil.getAllComAss(comAssessDTOS);
                    String lv = getLevel(allComAss);
                    comAssessVO.setData(allComAss);
                    comAssessVO.setLevel(lv);
                }
                comAssessVOList.add(comAssessVO);
            }
        }

        return comAssessVOList;
    }

    private void setResults(List<PQSComAssesPO> pqsComAssesPOS, List<ComAssessDTO> comAssessDTOS) {
        for (int i = 0; i < pqsComAssesPOS.size(); i++) {
            float v1 = new BigDecimal(pqsComAssesPOS.get(i).getVuDev1()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            ComAssessDTO comAssessDTO = new ComAssessDTO();
            comAssessDTO.setVuDev1(v1);
            float v2 = new BigDecimal(pqsComAssesPOS.get(i).getVuDev2()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setVuDev2(v2);
            float v3 = new BigDecimal(pqsComAssesPOS.get(i).getVuDev3()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setVuDev3(v3);
            float v4 = new BigDecimal(pqsComAssesPOS.get(i).getVuDev4()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setVuDev4(v4);
            float v5 = new BigDecimal(pqsComAssesPOS.get(i).getVuDev5()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setVuDev5(v5);
            float f1 = new BigDecimal(pqsComAssesPOS.get(i).getFreqDev1()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setFreqDev1(f1);
            float f2 = new BigDecimal(pqsComAssesPOS.get(i).getFreqDev2()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setFreqDev2(f2);
            float f3 = new BigDecimal(pqsComAssesPOS.get(i).getFreqDev3()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setFreqDev3(f3);
            float f4 = new BigDecimal(pqsComAssesPOS.get(i).getFreqDev4()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setFreqDev4(f4);
            float f5 = new BigDecimal(pqsComAssesPOS.get(i).getFreqDev5()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setFreqDev5(f5);
            float d1 = new BigDecimal(pqsComAssesPOS.get(i).getDataPST1()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setDataPST1(d1);
            float d2 = new BigDecimal(pqsComAssesPOS.get(i).getDataPST2()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setDataPST2(d2);
            float d3 = new BigDecimal(pqsComAssesPOS.get(i).getDataPST3()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setDataPST3(d3);
            float d4 = new BigDecimal(pqsComAssesPOS.get(i).getDataPST4()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setDataPST4(d4);
            float d5 = new BigDecimal(pqsComAssesPOS.get(i).getDataPST5()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setDataPST5(d5);
            float vu1 = new BigDecimal(pqsComAssesPOS.get(i).getVUnbalance1()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setVUnbalance1(vu1);
            float vu2 = new BigDecimal(pqsComAssesPOS.get(i).getVUnbalance2()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setVUnbalance2(vu2);
            float vu3 = new BigDecimal(pqsComAssesPOS.get(i).getVUnbalance3()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setVUnbalance3(vu3);
            float vu4 = new BigDecimal(pqsComAssesPOS.get(i).getVUnbalance4()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setVUnbalance4(vu4);
            float vu5 = new BigDecimal(pqsComAssesPOS.get(i).getVUnbalance5()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setVUnbalance5(vu5);
            float vt1 = new BigDecimal(pqsComAssesPOS.get(i).getVTHD1()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setVTHD1(vt1);
            float vt2 = new BigDecimal(pqsComAssesPOS.get(i).getVTHD2()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setVTHD2(vt2);
            float vt3 = new BigDecimal(pqsComAssesPOS.get(i).getVTHD3()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setVTHD3(vt3);
            float vt4 = new BigDecimal(pqsComAssesPOS.get(i).getVTHD4()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setVTHD4(vt4);
            float vt5 = new BigDecimal(pqsComAssesPOS.get(i).getVTHD5()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setVTHD5(vt5);
            float e1 = new BigDecimal(pqsComAssesPOS.get(i).getEvent1()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setEvent1(e1);
            float e2 = new BigDecimal(pqsComAssesPOS.get(i).getEvent2()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setEvent2(e2);
            float e3 = new BigDecimal(pqsComAssesPOS.get(i).getEvent3()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setEvent3(e3);
            float e4 = new BigDecimal(pqsComAssesPOS.get(i).getEvent4()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setEvent4(e4);
            float e5 = new BigDecimal(pqsComAssesPOS.get(i).getEvent5()).setScale(4, BigDecimal.ROUND_HALF_UP).floatValue();
            comAssessDTO.setEvent5(e5);
            comAssessDTOS.add(comAssessDTO);
        }
    }

    //获取综合评估等级
    private String getLevel(float synDatas) {
        if(synDatas==3.14159f){
            return "（暂无数据）";
        }
        if(0<=synDatas&&synDatas<2){
            return "极差";
        }else if(2<=synDatas&&synDatas<3){
            return "较差";
        }else if(3<=synDatas&&synDatas<4){
            return "合格";
        }else if(4<=synDatas&&synDatas<4.5){
            return "良好";
        }else{
            return  "优质";
        }
    }


    /**
     * influxDB查询综合评估相关信息
     * @param lineIndexes
     * @param searchBeginTime
     * @param searchEndTime
     */
    private List<PQSComAssesPO> getComAccessData(List<String> lineIndexes, String searchBeginTime, String searchEndTime) {
        //组装sql语句
        StringBuilder builder = new StringBuilder();
        builder.append("MEAN(VU_Dev1)AS VU_Dev1, MEAN(VU_Dev2)AS VU_Dev2, MEAN(VU_Dev3)AS VU_Dev3, MEAN(VU_Dev4)AS VU_Dev4, MEAN(VU_Dev5)AS VU_Dev5, MEAN(Freq_Dev1)AS Freq_Dev1, MEAN(Freq_Dev2)AS Freq_Dev2, MEAN(Freq_Dev3)AS Freq_Dev3, MEAN(Freq_Dev4)AS Freq_Dev4, MEAN(Freq_Dev5)AS Freq_Dev5, MEAN(Data_PST1)AS Data_PST1, MEAN(Data_PST2)AS Data_PST2, MEAN(Data_PST3)AS Data_PST3, MEAN(Data_PST4)AS Data_PST4, MEAN(Data_PST5)AS Data_PST5, MEAN(V_Unbalance1)AS V_Unbalance1, MEAN(V_Unbalance2)AS V_Unbalance2, MEAN(V_Unbalance3)AS V_Unbalance3, MEAN(V_Unbalance4)AS V_Unbalance4, MEAN(V_Unbalance5)AS V_Unbalance5, MEAN(V_THD1)AS V_THD1, MEAN(V_THD2)AS V_THD2, MEAN(V_THD3)AS V_THD3, MEAN(V_THD4)AS V_THD4, MEAN(V_THD5)AS V_THD5, MEAN(Event1)AS Event1, MEAN(Event2)AS Event2, MEAN(Event3)AS Event3, MEAN(Event4)AS Event4, MEAN(Event5)AS Event5");
        StringBuffer string = new StringBuffer();
        string.append(Param.TIME + " >= '" + searchBeginTime + Param.START_TIME + "' and " + Param.TIME + " <= '" + searchEndTime + Param.END_TIME + "' and ");
        for (int i = 0; i < lineIndexes.size(); i++) {
            if (lineIndexes.size() - i != 1) {
                string.append(Param.LINEID + "='").append(lineIndexes.get(i)).append("' or ");
            } else {
                string.append(Param.LINEID + "='").append(lineIndexes.get(i)).append("' group by " + Param.LINEID);
            }
        }

        //sql语句
        String sql = "SELECT "+ builder +" FROM PQS_COMASSES WHERE " + string;
        //结果集
        QueryResult result = influxDbUtils.query(sql);
        //结果集映射到对象中
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        List<PQSComAssesPO> pqsComAssesPOS = resultMapper.toPOJO(result, PQSComAssesPO.class);


        return pqsComAssesPOS;
    }


}
