package com.njcn.csharmonic.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.tocrhz.mqtt.publisher.MqttPublisher;
import com.njcn.access.api.CsTopicFeignClient;
import com.njcn.access.enums.AccessEnum;
import com.njcn.access.enums.TypeEnum;
import com.njcn.access.pojo.dto.AskDataDto;
import com.njcn.access.pojo.dto.ReqAndResDto;
import com.njcn.csdevice.api.CsLineFeignClient;
import com.njcn.csdevice.api.EquipmentFeignClient;
import com.njcn.csdevice.api.WlRecordFeignClient;
import com.njcn.csdevice.pojo.dto.CsEquipmentDeliveryDTO;
import com.njcn.csdevice.pojo.param.WlRecordParam;
import com.njcn.csdevice.pojo.po.CsDataSet;
import com.njcn.csdevice.pojo.po.CsEquipmentDeliveryPO;
import com.njcn.csdevice.pojo.po.CsLinePO;
import com.njcn.csdevice.pojo.po.WlRecord;
import com.njcn.csdevice.pojo.vo.DataGroupEventVO;
import com.njcn.csdevice.pojo.vo.EachModuleVO;
import com.njcn.csdevice.pojo.vo.RecordVo;
import com.njcn.csharmonic.constant.HarmonicConstant;
import com.njcn.csharmonic.mapper.CsDataSetMapper;
import com.njcn.csharmonic.param.DataParam;
import com.njcn.csharmonic.pojo.po.CsEventPO;
import com.njcn.csharmonic.pojo.vo.RealTimeDataVo;
import com.njcn.csharmonic.service.CsEventPOService;
import com.njcn.csharmonic.service.IDataService;
import com.njcn.csharmonic.util.InfluxDbParamUtil;
import com.njcn.influx.pojo.bo.CommonQueryParam;
import com.njcn.influx.pojo.dto.EventDataSetDTO;
import com.njcn.influx.pojo.dto.StatisticalDataDTO;
import com.njcn.influx.service.CommonService;
import com.njcn.influx.service.EvtDataService;
import com.njcn.redis.pojo.enums.AppRedisKey;
import com.njcn.redis.utils.RedisUtil;
import com.njcn.system.api.CsStatisticalSetFeignClient;
import com.njcn.system.api.DictTreeFeignClient;
import com.njcn.system.api.EleEvtFeignClient;
import com.njcn.system.api.EpdFeignClient;
import com.njcn.system.pojo.po.EleEpdPqd;
import com.njcn.system.pojo.po.EleEvtParm;
import com.njcn.system.pojo.vo.DictTreeVO;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 类的介绍：
 *
 * @author xuyang
 * @version 1.0.0
 * @createTime 2023/6/1 10:11
 */
@Service
@AllArgsConstructor
public class DataServiceImpl implements IDataService {

    private final CommonService commonService;
    private final CsStatisticalSetFeignClient csStatisticalSetFeignClient;
    private final DictTreeFeignClient dictTreeFeignClient;
    private final InfluxDbParamUtil influxDbParamUtil;
    private final CsLineFeignClient csLineFeignClient;
    private final CsDataSetMapper csDataSetMapper;
    private final WlRecordFeignClient wlRecordFeignClient;
    private final CsEventPOService csEventPOService;
    private final DecimalFormat df = new DecimalFormat("#0.00");
    private final EpdFeignClient epdFeignClient;
    private final EvtDataService evtDataService;
    private final EleEvtFeignClient eleEvtFeignClient;
    private final EquipmentFeignClient equipmentFeignClient;
    private final RedisUtil redisUtil;
    private static Integer mid = 1;
    private final CsTopicFeignClient csTopicFeignClient;
    private final MqttPublisher publisher;
    private static final List<String> ONLINE_STATES = Arrays.asList("运行", "停止", "故障");

    @Override
    public List<RealTimeDataVo> getRealTimeData(DataParam param) {
        List<RealTimeDataVo> result = new ArrayList<>();
        //获取监测点使用的数据集
        List<CsLinePO> finalCsLinePOList = csLineFeignClient.queryLineById(Collections.singletonList(param.getLineId())).getData();
        CsDataSet csDataSet = csDataSetMapper.selectOne(new LambdaQueryWrapper<CsDataSet>().eq(CsDataSet::getId,finalCsLinePOList.get(0).getDataSetId()));
        Double ct = finalCsLinePOList.get(0).getCtRatio();
        Double pt = finalCsLinePOList.get(0).getPtRatio();
        //根据类型id获取指标分组
        List<DictTreeVO> dictTreeVOList = dictTreeFeignClient.query(param.getTargetType()).getData();
        if (CollUtil.isNotEmpty(dictTreeVOList)) {
            dictTreeVOList = dictTreeVOList.stream().sorted(Comparator.comparing(DictTreeVO::getSort)).collect(Collectors.toList());
            //根据分组获取对应指标
            List<RealTimeDataVo> finalResult = result;
            dictTreeVOList.forEach(item->{
                List<EleEpdPqd> epdPqdList = csStatisticalSetFeignClient.queryStatisticalSelect(item.getId()).getData();
                epdPqdList.forEach(item2->{
                    if (Objects.isNull(item2.getHarmStart())) {
                        RealTimeDataVo vo = getBaseData(item2,param.getLineId(),param.getDataLevel(),csDataSet.getDataLevel(),pt,ct);
                        if (Objects.nonNull(vo)) {
                            finalResult.add(vo);
                        }
                    } else if (Objects.equals(item2.getHarmStart(),2)) {
                        List<RealTimeDataVo> harmList = getHarmData(item2,param.getLineId());
                        finalResult.addAll(harmList);
                    } else if (Objects.equals(item2.getHarmStart(),1)) {
                        List<RealTimeDataVo> inuharmList = getInuHarmData(item2,param.getLineId());
                        finalResult.addAll(inuharmList);
                    }
                });
            });
        }
        if (CollUtil.isNotEmpty(result)) {
            result = channelData(result);
        }
        return result;
    }

    @Override
    public List<RecordVo> getTestData(DataParam param) {
        WlRecordParam.lineRecord record = new WlRecordParam.lineRecord();
        record.setLineId(param.getLineId());
        String beginDay = LocalDateTimeUtil.format(LocalDateTimeUtil.beginOfDay(LocalDateTimeUtil.parse(param.getStartTime(), DatePattern.NORM_DATE_PATTERN)),DatePattern.NORM_DATETIME_PATTERN);
        String endDay = LocalDateTimeUtil.format(LocalDateTimeUtil.endOfDay(LocalDateTimeUtil.parse(param.getEndTime(), DatePattern.NORM_DATE_PATTERN)),DatePattern.NORM_DATETIME_PATTERN);
        record.setItemStartTime(beginDay);
        record.setItemEndTime(endDay);
        record.setDataSource(param.getDataSource());
        List<RecordVo> list = wlRecordFeignClient.findDevBaseDataByLineId(record).getData();
        if (CollUtil.isNotEmpty(list)) {
            list.forEach(item->{
                if (Objects.nonNull(item.getEndTime())) {
                    Duration duration = Duration.between(item.getStartTime(), item.getEndTime());
                    long totalMinutes = duration.toMinutes();
                    long completeHours = totalMinutes / 60;
                    long remainingMinutes = totalMinutes % 60;
                    long millis = duration.getSeconds();
                    if (completeHours == 0 && remainingMinutes == 0 && millis <= 60) {
                        remainingMinutes = 1;
                    }
                    item.setLastTime(completeHours + "小时" + remainingMinutes + "分钟");
                }
            });
        }
        return list;
    }

    @Override
    public List<DataGroupEventVO> getEventByItem(String id) {
        List<DataGroupEventVO> result = new ArrayList<>();
        List<WlRecord> list = wlRecordFeignClient.getWlAssByWlId(id).getData();
        if (CollUtil.isNotEmpty(list)) {
            list.forEach(item->{
                List<DataGroupEventVO> eventList = csEventPOService.queryEventList(item.getStartTime(),item.getEndTime(),item.getLineId());
                result.addAll(eventList);
            });
        }
        if (CollUtil.isNotEmpty(result)) {
            result.forEach(temp->{
                String lineName = csLineFeignClient.getById(temp.getLineId()).getData().getName();
                temp.setLineName(lineName);
                List<CsEquipmentDeliveryDTO> dto = equipmentFeignClient.queryDeviceById(Collections.singletonList(temp.getDeviceId())).getData();
                if (CollUtil.isNotEmpty(dto)) {
                    String devName = dto.get(0).getName();
                    temp.setDevName(devName);
                }

                EleEpdPqd ele = epdFeignClient.findByName(temp.getTag()).getData();
                if(ele!=null){
                    temp.setShowName(ele.getShowName());
                    //相别
                    List<EleEvtParm> data1 = eleEvtFeignClient.queryByPid(ele.getId()).getData();
                    List<EventDataSetDTO> eventDataSetDTOS = new ArrayList<>();
                    for (EleEvtParm eleEvtParm : data1) {
                        EventDataSetDTO eventDataSetDTO = new EventDataSetDTO();
                        BeanUtils.copyProperties(eleEvtParm,eventDataSetDTO);
                        EventDataSetDTO evtData = evtDataService.getEventDataSet(com.njcn.csdevice.constant.DataParam.evtData, temp.getId(), eleEvtParm.getName());
                        if (evtData == null) {
                            eventDataSetDTO.setValue("-");
                        }else {
                            eventDataSetDTO.setValue(Optional.ofNullable(evtData.getValue()).orElse("-"));
                        }
                        eventDataSetDTOS.add(eventDataSetDTO);
                    }
                    List<EventDataSetDTO> evtParamPhase = eventDataSetDTOS.stream().
                            filter(dataSetDTO -> Objects.equals(dataSetDTO.getName(), com.njcn.csdevice.constant.DataParam.EvtParamPhase)).
                            collect(Collectors.toList());
                    if(CollectionUtil.isEmpty(evtParamPhase)){
                        temp.setPhaseType(null);
                    }else {
                        temp.setPhaseType(evtParamPhase.get(0).getValue()+(Objects.isNull(evtParamPhase.get(0).getUnit())?"":evtParamPhase.get(0).getUnit()));
                    }

                    List<EventDataSetDTO> evtParamDepth = eventDataSetDTOS.stream().
                            filter(dataSetDTO -> Objects.equals(dataSetDTO.getName(), com.njcn.csdevice.constant.DataParam.EvtParamDepth)).
                            collect(Collectors.toList());
                    if(CollectionUtil.isEmpty(evtParamDepth)){
                        temp.setFeatureAmplitude(null);
                    }else {
                        temp.setFeatureAmplitude("-".equals(evtParamDepth.get(0).getValue())?null:Float.parseFloat(evtParamDepth.get(0).getValue()));
                    }
                    List<EventDataSetDTO> evtParmTm = eventDataSetDTOS.stream().
                            filter(dataSetDTO -> Objects.equals(dataSetDTO.getName(), com.njcn.csdevice.constant.DataParam.EVTPARAMTM)).
                            collect(Collectors.toList());
                    if(CollectionUtil.isEmpty(evtParamDepth)){
                        temp.setPersistTime(null);
                    }else {
                        temp.setPersistTime("-".equals(evtParmTm.get(0).getValue())?null:Double.parseDouble(evtParmTm.get(0).getValue()));
                    }
                }
            });
        }
        return result;
    }

    @Override
    public List<EachModuleVO> allModelData(DataParam param) {
        List<EachModuleVO> result = new ArrayList<>();
        //根据监测点查询装置信息
        CsEquipmentDeliveryPO po = equipmentFeignClient.getDevByLineId(param.getLineId()).getData();
        if (ObjectUtil.isNotNull(po.getModuleNumber())) {

            CommonQueryParam commonQueryParam = new CommonQueryParam();
            commonQueryParam.setColumnName("Apf_ModWorkingSts");
            commonQueryParam.setResultName("value");
            commonQueryParam.setTableName("apf_data");
            commonQueryParam.setStartTime(param.getStartTime()+" 00:00:00");
            commonQueryParam.setEndTime(param.getEndTime()+" 23:59:59");
            commonQueryParam.setLineId(param.getLineId());
            commonQueryParam.setDataType("Apf_ModType");
            commonQueryParam.setProcess(Integer.toString(po.getProcess()));
            for (int i = 1; i <= po.getModuleNumber(); i++) {
                EachModuleVO moduleVO = new EachModuleVO();
                moduleVO.setModuleName("模块"+i);

                List<EachModuleVO.HarmonicVo> list1 = new ArrayList<>();
                commonQueryParam.setClDid(Integer.toString(i));

                List<EachModuleVO.DataVo> list2 = new ArrayList<>();
                List<EachModuleVO.DataVo> list3 = new ArrayList<>();
                List<EachModuleVO.DataVo> list4 = new ArrayList<>();

                //获取模块状态数据
                List<StatisticalDataDTO> dto = commonService.getEachModule(commonQueryParam);
                if (CollectionUtil.isNotEmpty(dto)) {
                    dto.forEach(item->{
                        EachModuleVO.HarmonicVo vo = new EachModuleVO.HarmonicVo();
                        vo.setTime(LocalDateTime.ofInstant(item.getTime().minus(8, ChronoUnit.HOURS), ZoneId.systemDefault()));
                        vo.setStateDesc(channelState(item.getValue()));
                        vo.setDataType(0);
                        list1.add(vo);
                    });
                } else {
                    moduleVO.setModuleState("离线");
                }

                //获取模块电流数据
                List<StatisticalDataDTO> dto2 = commonService.getModuleData(commonQueryParam);
                if (CollectionUtil.isNotEmpty(dto2)) {
                    dto2.forEach(item->{

                        EachModuleVO.DataVo vo1 = new EachModuleVO.DataVo();
                        vo1.setTime(LocalDateTime.ofInstant(item.getTime().minus(8, ChronoUnit.HOURS), ZoneId.systemDefault()));
                        vo1.setPhasicType(item.getPhaseType());
                        vo1.setData(Objects.isNull(item.getValue()) ? 3.14159 : Double.parseDouble(df.format(item.getValue())));

                        EachModuleVO.DataVo vo2 = new EachModuleVO.DataVo();
                        vo2.setTime(LocalDateTime.ofInstant(item.getTime().minus(8, ChronoUnit.HOURS), ZoneId.systemDefault()));
                        vo2.setPhasicType(item.getPhaseType());
                        vo2.setData(Objects.isNull(item.getAvgValue()) ? 3.14159 : Double.parseDouble(df.format(item.getAvgValue())));

                        if (Objects.equals(item.getPhaseType(),"M")) {
                            EachModuleVO.DataVo vo3 = new EachModuleVO.DataVo();
                            vo3.setTime(LocalDateTime.ofInstant(item.getTime().minus(8, ChronoUnit.HOURS), ZoneId.systemDefault()));
                            vo3.setPhasicType(item.getPhaseType());
                            vo3.setData(Objects.isNull(item.getMinValue()) ? 3.14159 : Double.parseDouble(df.format(item.getMinValue())));
                            list4.add(vo3);
                        }
                        list2.add(vo1);
                        list3.add(vo2);
                    });
                }

                //获取模块事件
                LambdaQueryWrapper<CsEventPO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(CsEventPO::getLineId, param.getLineId())
                        .between(CsEventPO::getStartTime,param.getStartTime()+" 00:00:00",param.getEndTime()+" 23:59:59")
                        .eq(CsEventPO::getClDid,i)
                        .eq(CsEventPO::getProcess,Integer.toString(po.getProcess()))
                        .orderByAsc(CsEventPO::getStartTime);
                List<CsEventPO> eventList = csEventPOService.list(lambdaQueryWrapper);
                if (CollectionUtil.isNotEmpty(eventList)) {
                    eventList.forEach(item->{
                        EleEpdPqd epdPqd = epdFeignClient.findByName(item.getTag()).getData();
                        EachModuleVO.HarmonicVo vo = new EachModuleVO.HarmonicVo();
                        vo.setTime(item.getStartTime());
                        //查询事件状态 如果往前查寻没有数据、则往后查询事件
                        if (Objects.equals("Alm_Apf_ModConnect",item.getTag())) {
                            if (ObjectUtil.isNotEmpty(list1)) {
                                Optional<EachModuleVO.HarmonicVo> optional = list1.stream()
                                        // 筛选时间早于参考时间且目标字段等于指定值的记录
                                        .filter(vo1 -> vo1.getTime().isBefore(item.getStartTime()))
                                        .filter(vo2 -> vo2.getDataType() == 0)
                                        .findFirst();
                                optional.ifPresent(harmonicVo -> vo.setStateDesc(harmonicVo.getStateDesc()));
                            }
                        } else {
                            vo.setStateDesc(channelState2(item.getTag()));
                        }
                        vo.setEventCode(item.getTag());
                        vo.setDataType(1);
                        if (ObjectUtil.isNotNull(epdPqd)) {
                            vo.setEventName(epdPqd.getShowName());
                        } else {
                            vo.setEventName(item.getTag());
                        }
                        list1.add(vo);
                    });
                }
                if (CollectionUtil.isNotEmpty(list1)) {
                    List<EachModuleVO.HarmonicVo> dataList = list1.stream()
                            .sorted(Comparator.comparing(EachModuleVO.HarmonicVo::getTime))
                            .collect(Collectors.toList());
                    //处理APF模块连接事件状态
                    dataList.forEach(item->{
                        if (Objects.equals(item.getEventCode(),"Alm_Apf_ModConnect")) {
                            Optional<EachModuleVO.HarmonicVo> optional = dataList.stream()
                                    // 筛选时间早于参考时间且目标字段等于指定值的记录
                                    .filter(vo1 -> vo1.getTime().isAfter(item.getTime()) && vo1.getDataType() == 1)
                                    .filter(vo2 -> !Objects.equals("Alm_Apf_ModDisConnect",vo2.getEventCode()) && !Objects.equals("Alm_Apf_ModConnect",vo2.getEventCode()))
                                    .findFirst();
                            if (optional.isPresent()) {
                                item.setStateDesc(optional.get().getStateDesc());
                            } else {
                                item.setStateDesc("无状态");
                            }
                        }
                    });

                    EachModuleVO.HarmonicVo last = dataList.get(dataList.size() - 1);
                    moduleVO.setModuleState(last.getStateDesc());
                    //如果模块掉线超过30分钟，则续上数据
                    int timeCompare = compareWithCurrentTime(commonQueryParam.getEndTime());
                    LocalDateTime currentTime;
                    switch (timeCompare) {
                        case -1:
                        case 0:
                            currentTime = LocalDateTime.now();
                            break;
                        case 1:
                            currentTime = LocalDateTime.parse(commonQueryParam.getEndTime(), DatePattern.NORM_DATETIME_FORMATTER);
                            break;
                        default:
                            currentTime = LocalDateTime.now();
                            System.out.println("比较失败");
                    }

                    LocalDateTime givenTime = last.getTime();
                    Duration duration = Duration.between(givenTime, currentTime);
                    boolean isMoreThan30Minutes = duration.toMinutes() > 30;
                    if (isMoreThan30Minutes) {
                        EachModuleVO.HarmonicVo vo = new EachModuleVO.HarmonicVo();
                        vo.setTime(currentTime);
                        vo.setStateDesc(last.getStateDesc());
                        vo.setDataType(0);
                        dataList.add(vo);
                    }
                    moduleVO.setDataList(dataList);
                }
                moduleVO.setModOutList(list2);
                moduleVO.setLoadList(list3);
                moduleVO.setTemperatureList(list4);
                result.add(moduleVO);
            }
        }
        return result;
    }

    @Override
    public List<EachModuleVO> getModuleState(String nDid) {
        List<EachModuleVO> result = new ArrayList<>();
        try {
            CsEquipmentDeliveryPO po = equipmentFeignClient.findDevByNDid(nDid).getData();
            for (int i = 1; i <= po.getModuleNumber(); i++) {
                EachModuleVO moduleVO = new EachModuleVO();
                moduleVO.setModuleName("模块"+i);
                Object object = redisUtil.getObjectByKey(AppRedisKey.DEVICE_MID + nDid);
                if (!Objects.isNull(object)) {
                    mid = (Integer) object;
                }
                ReqAndResDto.Req dto = askApfModuleData(mid,i,i);
                String version = csTopicFeignClient.find(nDid).getData();
                publisher.send("/Pfm/DevCmd/" + version + "/" + nDid, new Gson().toJson(dto), 1, false);
                Thread.sleep(800);
                Object redisUtilObjectByKey = redisUtil.getObjectByKey("ApfRtData:" + mid);
                if (ObjectUtil.isNotNull(redisUtilObjectByKey)) {
                    Double value = Double.parseDouble(redisUtilObjectByKey.toString());
                    moduleVO.setModuleState(channelState(value));
                } else {
                    //再询问一次
                    publisher.send("/Pfm/DevCmd/" + version + "/" + nDid, new Gson().toJson(dto), 1, false);
                    Thread.sleep(800);
                    Object redisUtilObjectByKey2 = redisUtil.getObjectByKey("ApfRtData:" + mid);
                    if (ObjectUtil.isNotNull(redisUtilObjectByKey2)) {
                        Double value = Double.parseDouble(redisUtilObjectByKey2.toString());
                        moduleVO.setModuleState(channelState(value));
                    } else {
                        moduleVO.setModuleState("离线");
                    }
                }
                mid = mid + 1;
                if (mid > 10000) {
                    mid = 1;
                }
                redisUtil.saveByKey(AppRedisKey.DEVICE_MID + nDid,mid);
                result.add(moduleVO);
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    public int compareWithCurrentTime(String timeString) {
        // 定义日期时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 解析字符串时间为LocalDateTime对象
        LocalDateTime specifiedTime = LocalDateTime.parse(timeString, formatter);
        // 获取当前时间
        LocalDateTime currentTime = LocalDateTime.now();
        // 比较两个时间
        return currentTime.compareTo(specifiedTime);
    }


    public ReqAndResDto.Req askApfModuleData(Integer mid, Integer clDId, Integer idx) {
        ReqAndResDto.Req reqAndResParam = new ReqAndResDto.Req();
        reqAndResParam.setMid(mid);
        reqAndResParam.setPri(AccessEnum.FIRST_CHANNEL.getCode());
        reqAndResParam.setType(Integer.parseInt(TypeEnum.TYPE_6.getCode()));
        reqAndResParam.setExpire(-1);
        //fixme 目前设备都是直连设备，因此did就是其本身，默认为1，后期涉及网关，此did是需要动态变化的
        reqAndResParam.setDid(1);
        AskDataDto askDataDto = new AskDataDto();
        askDataDto.setCldid(clDId);
        askDataDto.setDataAttr(1);
        askDataDto.setDataType(15);
        askDataDto.setOperate(1);
        askDataDto.setStartTime(-1);
        askDataDto.setEndTime(-1);
        askDataDto.setDsNameIdx(idx);
        reqAndResParam.setMsg(askDataDto);
        return reqAndResParam;
    }

    public String channelState(Double value) {
        String str;
        int val = (int) Math.round(value);
        switch (val) {
            case 0:
                str = "离线";
                break;
            case 1:
                str = "停止";
                break;
            case 2:
                str = "运行";
                break;
            case 3:
                str = "故障";
                break;
            default:
                str = "无状态";
                break;
        }
        return str;
    }

    public String channelState2(String code) {
        String str = null;
        if ("Alm_Apf_ModDisConnect".equals(code)) {
            str = "离线";
        } else if ("Alm_Apf_ModRunStop".equals(code) || "Alm_Apf_JT_stsLock".equals(code) || "Alm_Apf_JT_stsUnLock".equals(code)) {
            str = "停止";
        } else if ("Alm_Apf_ModRunRun".equals(code)) {
            str = "运行";
        } else if ("Alm_Apf_ModRunFault".equals(code)) {
            str = "故障";
        }
        return str;
    }

    //基础数据
    public RealTimeDataVo getBaseData(EleEpdPqd item2, String lineId, String dataLevel, String csDataSetLevel,Double pt, Double ct) {
        RealTimeDataVo vo = new RealTimeDataVo();
        String unit;
        double re;
        vo.setId(item2.getId());
        vo.setName(item2.getName());
        StatisticalDataDTO statisticalDataDTO = commonService.getLineRtData(lineId,influxDbParamUtil.getTableNameByClassId(item2.getClassId()),item2.getName(),item2.getPhase(),"avg",influxDbParamUtil.getClDidByLineId(lineId));
        if (Objects.nonNull(statisticalDataDTO)) {
            vo.setTime(statisticalDataDTO.getTime());
            vo.setAvgValue(statisticalDataDTO.getValue());
        }
        vo.setPhase(item2.getPhase());
        vo.setOtherName(item2.getShowName());
        vo.setSort(item2.getSort());
        if (Objects.equals("Primary",dataLevel)) {
            if (Objects.equals("Primary",csDataSetLevel)) {
                if (HarmonicConstant.POWER_LIST.contains(item2.getShowName())) {
                    re = Objects.isNull(statisticalDataDTO) ? 3.14159 : Double.parseDouble(df.format(statisticalDataDTO.getValue() / 1000));
                    vo.setAvgValue(re);
                    unit = "k" + item2.getUnit();
                } else {
                    vo.setAvgValue(Objects.isNull(statisticalDataDTO) ? 3.14159 : Double.parseDouble(df.format(statisticalDataDTO.getValue())));
                    unit = item2.getUnit();
                }
            } else {
                if(Objects.nonNull(item2.getPrimaryFormula())){
                    switch (item2.getPrimaryFormula()) {
                        case "*PT":
                            re = Objects.isNull(statisticalDataDTO) ? 3.14159 : statisticalDataDTO.getValue() * pt / 1000;
                            unit = "k" + item2.getUnit();
                            break;
                        case "*CT":
                            re = Objects.isNull(statisticalDataDTO) ? 3.14159 : statisticalDataDTO.getValue() * ct;
                            unit = item2.getUnit();
                            break;
                        case "*PT*CT":
                            re = Objects.isNull(statisticalDataDTO) ? 3.14159 : statisticalDataDTO.getValue() * pt * ct / 1000;
                            unit = "k" + item2.getUnit();
                            break;
                        default:
                            re = Objects.isNull(statisticalDataDTO) ? 3.14159 : statisticalDataDTO.getValue();
                            unit = item2.getUnit();
                            break;
                    }
                    vo.setAvgValue(Objects.equals(re,3.14159) ? 3.14159 : Double.parseDouble(df.format(re)));
                }else {
                    if (Objects.nonNull(statisticalDataDTO)) {
                        re = statisticalDataDTO.getValue();
                        vo.setAvgValue(Double.valueOf(df.format(re)));
                    }
                    unit = item2.getUnit();
                }
            }
        } else {
            if (Objects.equals("Primary",csDataSetLevel)) {
                if(Objects.nonNull(item2.getPrimaryFormula())) {
                    switch (item2.getPrimaryFormula()) {
                        case "*PT":
                            re = Objects.isNull(statisticalDataDTO) ? 3.14159 : statisticalDataDTO.getValue() / pt;
                            break;
                        case "*CT":
                            re = Objects.isNull(statisticalDataDTO) ? 3.14159 : statisticalDataDTO.getValue() / ct;
                            break;
                        case "*PT*CT":
                            re = Objects.isNull(statisticalDataDTO) ? 3.14159 : statisticalDataDTO.getValue() / pt / ct / 1000;
                            break;
                        default:
                            re = Objects.isNull(statisticalDataDTO) ? 3.14159 : statisticalDataDTO.getValue();
                            break;
                    }
                    vo.setAvgValue(Objects.equals(re,3.14159) ? 3.14159 : Double.parseDouble(df.format(re)));
                }else {
                    if (Objects.nonNull(statisticalDataDTO)) {
                        re = statisticalDataDTO.getValue();
                        vo.setAvgValue(Double.valueOf(df.format(re)));
                    }
                }
            } else {
                vo.setAvgValue(Objects.isNull(statisticalDataDTO) ? 3.14159 : Double.parseDouble(df.format(statisticalDataDTO.getValue())));
            }
            unit = item2.getUnit();
        }
        vo.setUnit(unit);
        if (Objects.nonNull(unit)) {
            vo.setOtherName(item2.getShowName() + "(" + unit + ")");
        }
        return vo;
    }

    //谐波数据
    public List<RealTimeDataVo> getHarmData(EleEpdPqd item2, String lineId) {
        List<RealTimeDataVo> list = new ArrayList<>();
        for (int i = item2.getHarmStart(); i <= item2.getHarmEnd(); i++) {
            RealTimeDataVo vo = new RealTimeDataVo();
            vo.setId(item2.getId());
            vo.setName(item2.getName().concat("_").concat(Integer.toString(i)));
            StatisticalDataDTO statisticalDataDTO = commonService.getLineRtData(lineId,influxDbParamUtil.getTableNameByClassId(item2.getClassId()),item2.getName().concat("_").concat(Integer.toString(i)),item2.getPhase(),"avg",influxDbParamUtil.getClDidByLineId(lineId));
            if (Objects.isNull(statisticalDataDTO)) {
                vo.setAvgValue(3.14159);
            } else {
                vo.setTime(statisticalDataDTO.getTime());
                vo.setAvgValue(Double.valueOf(df.format(statisticalDataDTO.getValue())));
            }
            vo.setPhase(item2.getPhase());
            vo.setOtherName(i + "次" + "(" + item2.getUnit() + ")");
            vo.setSort(item2.getSort());
            vo.setUnit(item2.getUnit());
            list.add(vo);
        }
        return list;
    }

    //间谐波数据
    public List<RealTimeDataVo> getInuHarmData(EleEpdPqd item2, String lineId) {
        List<RealTimeDataVo> list = new ArrayList<>();
        for (int i = item2.getHarmStart(); i <= item2.getHarmEnd(); i++) {
            RealTimeDataVo vo = new RealTimeDataVo();
            vo.setId(item2.getId());
            vo.setName(item2.getName().concat("_").concat(Integer.toString(i)));
            StatisticalDataDTO statisticalDataDTO = commonService.getLineRtData(lineId,influxDbParamUtil.getTableNameByClassId(item2.getClassId()),item2.getName().concat("_").concat(Integer.toString(i)),item2.getPhase(),"avg",influxDbParamUtil.getClDidByLineId(lineId));
            if (Objects.isNull(statisticalDataDTO)) {
                vo.setAvgValue(3.14159);
            } else {
                vo.setTime(statisticalDataDTO.getTime());
                vo.setAvgValue(Double.valueOf(df.format(statisticalDataDTO.getValue())));
            }
            vo.setPhase(item2.getPhase());
            vo.setOtherName((i-0.5) + "次" + "(" + item2.getUnit() + ")");
            vo.setSort(item2.getSort());
            vo.setUnit(item2.getUnit());
            list.add(vo);
        }
        return list;
    }

    //数据格式处理
    public  List<RealTimeDataVo> channelData(List<RealTimeDataVo> list) {
        AtomicReference<Instant> time = new AtomicReference<>();
        list.forEach(item->{
            if (Objects.equals(item.getName(),"Pq_Freq")) {
                time.set(item.getTime());
            }
        });
        if (Objects.nonNull(time.get())) {
            list.forEach(item->{
                if (ObjectUtil.isNotNull(item.getTime()) && item.getTime().isBefore(time.get())) {
                    item.setAvgValue(3.14159);
                    item.setValueA(3.14159);
                    item.setValueB(3.14159);
                    item.setValueC(3.14159);
                }
            });
        }

        List<RealTimeDataVo> result = new ArrayList<>();
        //将list 排序，并按照排序后的结果进行有序分组
        LinkedHashMap<String, List<RealTimeDataVo>> map = list.stream().sorted(Comparator.comparing(RealTimeDataVo::getSort)).collect(Collectors.groupingBy(RealTimeDataVo::getName, LinkedHashMap::new, Collectors.toList()));
        map.forEach((k,v)->{
            RealTimeDataVo vo = new RealTimeDataVo();
            RealTimeDataVo vo1 = v.get(0);
            BeanUtils.copyProperties(vo1,vo);
            RealTimeDataVo phaseA = v.stream().filter(s->Objects.equals(s.getPhase(),"A") || Objects.equals(s.getPhase(),"AB")).findFirst().orElse(null);
            if (Objects.nonNull(phaseA)) {
                vo.setValueA(Objects.isNull(phaseA.getAvgValue()) ? 3.14159 : phaseA.getAvgValue());
            }
            RealTimeDataVo phaseB = v.stream().filter(s->Objects.equals(s.getPhase(),"B") || Objects.equals(s.getPhase(),"BC")).findFirst().orElse(null);
            if (Objects.nonNull(phaseB)) {
                vo.setValueB(Objects.isNull(phaseB.getAvgValue()) ? 3.14159 : phaseB.getAvgValue());
            }
            RealTimeDataVo phaseC = v.stream().filter(s->Objects.equals(s.getPhase(),"C") || Objects.equals(s.getPhase(),"CA")).findFirst().orElse(null);
            if (Objects.nonNull(phaseC)) {
                vo.setValueC(Objects.isNull(phaseC.getAvgValue()) ? 3.14159 : phaseC.getAvgValue());
            }
            RealTimeDataVo phaseM = v.stream().filter(s->Objects.equals(s.getPhase(),"M")).findFirst().orElse(null);
            if (Objects.nonNull(phaseM)) {
                vo.setValueM(Objects.isNull(phaseM.getAvgValue()) ? 3.14159 : phaseM.getAvgValue());
            }
            vo.setPhase("/");
            vo.setAvgValue(null);
            result.add(vo);
        });
        return result;
    }

}
