package com.njcn.event.service.Impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.dto.wave.WaveDataDTO;
import com.njcn.common.pojo.enums.common.ServerEnum;
import com.njcn.common.utils.wave.AnalyWave;
import com.njcn.device.api.GeneralDeviceInfoClient;
import com.njcn.device.api.LineFeignClient;
import com.njcn.device.pojo.dto.GeneralDeviceDTO;
import com.njcn.device.pojo.vo.LineDetailDataVO;
import com.njcn.event.mapper.TransientMapper;
import com.njcn.event.pojo.param.TransientParam;
import com.njcn.event.pojo.po.EventDetail;
import com.njcn.event.pojo.vo.TransientVO;
import com.njcn.event.service.EventDetailService;
import com.njcn.event.service.TransientService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author: chenchao
 * @date: 2022/03/29 14:37
 * @Description: <描述>
 */
@Service
@AllArgsConstructor
public class TransientServiceImpl implements TransientService {

    private final GeneralDeviceInfoClient generalDeviceInfoClient;

    private final LineFeignClient lineFeignClient;

    private final TransientMapper transientMapper;

    private final EventDetailService eventDetailService;

    @Override
    public Page<TransientVO> getTransientData(TransientParam transientParam) {
        Page<TransientVO> page = new Page<>();
        page.setSize(transientParam.getPageSize());
        page.setCurrent(transientParam.getPageNum());
        List<TransientVO> transientVOS = new ArrayList<>();
        transientParam.setServerName(ServerEnum.HARMONIC.getName());
        List<GeneralDeviceDTO> deviceList = generalDeviceInfoClient.getPracticalRunDeviceInfo(transientParam).getData();
        if (!CollectionUtils.isEmpty(deviceList)) {
            List<List<String>> lists = deviceList.stream().map(GeneralDeviceDTO::getLineIndexes).collect(Collectors.toList());
            List<String> lineList = new ArrayList<>();
            for (int i = 0; i<lists.size(); i++) {
                List<String> strings1 = lists.get(i);
                for (int a = 0; a<strings1.size(); a++) {
                    lineList.add(strings1.get(a));
                }
            }
            if (!CollectionUtils.isEmpty(lineList)) {
                //influxDB查询待分页数据总量
                List<EventDetail> data = eventDetailService.getEventDetail(lineList, transientParam.getSearchBeginTime(), transientParam.getSearchEndTime());
                page.setTotal(data.size());
                //分页总页数
                int pages = (int)Math.ceil(data.size()*1.0/transientParam.getPageSize());
                page.setPages(pages);
                //influxDB分页查询
                List<EventDetail> eventDetailData = eventDetailService.getEventDetailLimit(lineList, transientParam.getSearchBeginTime(), transientParam.getSearchEndTime(),  transientParam.getPageSize(), transientParam.getPageNum());
                // List<List<EventDetail>> partition = Lists.partition(eventDetailData, transientParam.getPageSize());
                // List<EventDetail> detailList = partition.get(transientParam.getPageNum() - 1);
                if (!CollectionUtils.isEmpty(eventDetailData)) {
                    List<String> collect = eventDetailData.stream().map(EventDetail::getLineId).collect(Collectors.toList());
                    List<TransientVO> transientData = transientMapper.getTransientData(collect);
                    for (EventDetail eventDetail: eventDetailData) {
                        if (!Objects.isNull(eventDetail)) {
                            TransientVO transientVO = new TransientVO();
                            transientVO.setId(eventDetail.getLineId());

                            Instant timeId = eventDetail.getTimeId();
                            ZoneId zoneId = ZoneId.systemDefault();
                            LocalDateTime localDateTime = LocalDateTime.ofInstant(timeId, zoneId);
                            // //Instant转换long毫秒值
                            // long milli = localDateTime.atZone(zoneId).toInstant().toEpochMilli();
                            // System.out.println("milli==:" + milli);
                            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
                            String format = dateTimeFormatter.format(localDateTime);

                            transientVO.setTime(format);
                            switch (eventDetail.getWaveType()) {
                                case 0:
                                    transientVO.setTrigType("扰动");
                                    break;
                                case 1:
                                    transientVO.setTrigType("暂降");
                                    break;
                                case 2:
                                    transientVO.setTrigType("赞升");
                                    break;
                                case 3:
                                    transientVO.setTrigType("中断");
                                    break;
                                case 4:
                                    transientVO.setTrigType("其他");
                                    break;
                                case 5:
                                    transientVO.setTrigType("录波");
                                    break;
                            }
                            Double value = new BigDecimal(eventDetail.getEventValue()).setScale(3, BigDecimal.ROUND_DOWN).doubleValue();
                            transientVO.setEventValue(value);
                            Double values = new BigDecimal(1 - value).setScale(3, BigDecimal.ROUND_DOWN).doubleValue();
                            transientVO.setEventValues(values);
                            transientVO.setPersistTime((Float.parseFloat(eventDetail.getPersistTime().toString()))/1000);

                            Float eventValue = Float.parseFloat(eventDetail.getEventValue().toString());
                            transientVO.setYZD(getYZD(transientVO.getPersistTime(), eventValue));
                            transientVOS.add(transientVO);
                        }
                    }
                    transientVOS.stream().map(list1 -> transientData.stream().filter(list2 -> Objects.equals(list1.getId(), list2.getId())).findAny().map(m -> {
                        list1.setName(m.getName());
                        list1.setPowerCompany(m.getPowerCompany());
                        list1.setSubstation(m.getSubstation());
                        list1.setNetworkParam(m.getNetworkParam());
                        list1.setVoltageLevel(m.getVoltageLevel());
                        return list1;
                    })).collect(Collectors.toList());
                    //当前页数据
                    page.setRecords(transientVOS);
                }

            }

        }
        return page;
    }

    @Override
    public WaveDataDTO getTransientAnalyseWave(String timeId, String lineId) {
        //根据监测点id获取监测点详情
        LineDetailDataVO lineDetailData = lineFeignClient.getLineDetailData(lineId).getData();
        String ip = lineDetailData.getIp();
        EventDetail eventDetailByTime = eventDetailService.getEventDetailByTime(lineId, timeId);
        String waveName = eventDetailByTime.getWaveName();
        AnalyWave analyWave = new AnalyWave();
        System.out.println("path----------------------"+"C:\\Users\\陈超\\Desktop\\Comtrade\\"+ip+"\\"+waveName);
        WaveDataDTO comtrade = analyWave.getComtrade("C:\\Users\\陈超\\Desktop\\Comtrade\\192.168.0.58\\222.CFG", 1);
        // WaveDataDTO comtrade = analyWave.getComtrade("C:\\Users\\陈超\\Desktop\\Comtrade\\"+ip+"\\"+waveName, 1);
        WaveDataDTO waveDataDTO = analyWave.getValidData(comtrade);
        return waveDataDTO;
    }


    /**
     * 获取该事件的严重度
     *
     * @param persistTime 持续时间 ms单位
     * @param eventValue  暂降、暂升幅值
     */
    public static String getYZD(Float persistTime, Float eventValue) {
        float yzd;
        DecimalFormat df = new DecimalFormat("0.000");// 格式化小数
        if (persistTime <= 20) {
            yzd = 1 - eventValue;
        } else if (persistTime > 20 && persistTime <= 200) {
            yzd = 2 * (1 - eventValue);
        } else if (persistTime > 200 && persistTime <= 500) {
            yzd = 3.3f * (1 - eventValue);
        } else if (persistTime > 500 && persistTime <= 10000) {
            yzd = 5 * (1 - eventValue);
        } else {
            yzd = 10 * (1 - eventValue);
        }
        String tempOnlineRate = df.format(yzd);// 返回的是String类型
        return tempOnlineRate;
    }


}
