package com.njcn.event.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.njcn.common.pojo.enums.common.ServerEnum;
import com.njcn.device.api.GeneralDeviceInfoClient;
import com.njcn.device.api.LineFeignClient;
import com.njcn.device.pojo.dto.GeneralDeviceDTO;
import com.njcn.device.pojo.param.DeviceInfoParam;
import com.njcn.device.pojo.vo.LineDetailVO;
import com.njcn.device.pojo.vo.LineDeviceStateVO;
import com.njcn.event.pojo.vo.*;
import com.njcn.device.pojo.vo.SubstationDetailVO;
import com.njcn.event.service.AreaLineService;
import com.njcn.influxdb.utils.InfluxDbUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.influxdb.dto.QueryResult;
import org.influxdb.impl.InfluxDBResultMapper;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author denghuajun
 * @version 1.0.0
 * @date 2022年04月07日 13:39
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AreaLineServiceImpl implements AreaLineService {

    private final GeneralDeviceInfoClient generalDeviceInfoClient;

    private final LineFeignClient lineFeignClient;

    private final InfluxDbUtils influxDbUtils;


    @Override
    public AreaLineVO getAreaLineVO(DeviceInfoParam deviceInfoParam) {
        AreaLineVO areaLineVO = new AreaLineVO();
        deviceInfoParam.setServerName(ServerEnum.EVENT.getName());
        List<List<Object>> listObject = new ArrayList<>();
        //获取暂降监测点
        List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceInfoClient.getPracticalAllDeviceInfo(deviceInfoParam).getData();
        List<String> lineIndexs;
        List<SubstationDetailVO> substationDetailVOList = new ArrayList<>();
        //获取所有终端信息
        for (GeneralDeviceDTO generalDeviceDTO : generalDeviceDTOList) {
            List<Object> objectList = new ArrayList<>();
            List<String> subIndexs;
            subIndexs = generalDeviceDTO.getSubIndexes();
            lineIndexs = generalDeviceDTO.getLineIndexes();
            //通讯正常个数
            int stateZc = 0;
            //通讯中断个数
            int stateZd = 0;
            //总次数
            int tail = 0;

            String color = "";
            List<SubstationDetailVO> substationDetailVOS = new ArrayList<>();
            if (subIndexs.size() > 0) {
                List<LineDeviceStateVO> lineList = lineFeignClient.getAllLine(lineIndexs).getData();
                substationDetailVOS = lineFeignClient.getSubstationData(subIndexs).getData();
                for (int i = 0; i < substationDetailVOS.size(); i++) {
                    List<LineDeviceStateVO> list = new ArrayList<>();
                    list.addAll(lineList);
                    Iterator<LineDeviceStateVO> iterator = list.listIterator();
                    //获取监测点
                    while (iterator.hasNext()) {
                        LineDeviceStateVO line = iterator.next();
                        String[] ids = line.getPids().split(",");
                        if (!ids[3].equals(substationDetailVOS.get(i).getId())) {
                            iterator.remove();
                        }
                    }
                    List<LineDeviceStateVO> lineDataVOList = list;
                    //通讯正常个数
                    int stateTrue;
                    stateTrue = 0;
                    //通讯中断个数
                    int stateFalse = 0;
                    //次数
                    double r = 0.0035;

                    int j = 0;
                    //总的监测点个数
                    int lineTail = lineDataVOList.size();
                    for (LineDeviceStateVO lineDataVO : lineDataVOList) {
                        if (lineDataVO.getState() == 1) {
                            stateTrue++;
                            color = "green";
                        } else {
                            stateFalse++;
                            color = "red";
                        }
                        SubstationDetailVO substationDetail = new SubstationDetailVO();
                        substationDetail.setId(lineDataVO.getId());
                        substationDetail.setSrbName(lineDataVO.getName());
                        substationDetail.setCoordY(substationDetailVOS.get(i).getCoordY().floatValue() + r * Math.cos(2 * Math.PI * j / lineTail));
                        substationDetail.setCoordX(substationDetailVOS.get(i).getCoordX().floatValue() + r * Math.sin(2 * Math.PI * j / lineTail));
                        substationDetail.setColor(color);
                        substationDetailVOList.add(substationDetail);
                        j++;
                    }
                    stateZc += stateTrue;
                    stateZd += stateFalse;
                    tail += lineTail;
                }
            }
            //获取变电站
            substationDetailVOList.addAll(substationDetailVOS);
            if (lineIndexs.size() > 0) {
                areaLineVO.setSubstationDetailVOList(substationDetailVOList);
                objectList.add(generalDeviceDTO.getName()+"\n("+tail+")");
                objectList.add(tail);
                objectList.add(stateZc);
                objectList.add(stateZd);
                listObject.add(objectList);
            }
        }
        areaLineVO.setAreaValue(listObject);
        return areaLineVO;
    }

    @Override
    public EventHeatMapVO getEventHeatMap(DeviceInfoParam.BusinessParam deviceInfoParam) {
        EventHeatMapVO eventHeatMapVO = new EventHeatMapVO();
        List<EventHeatMapDetailVO> eventHeatMapDetailList = new ArrayList<>();
        deviceInfoParam.setServerName(ServerEnum.EVENT.getName());
        List<List<Object>> listObject = new ArrayList<>();
        //获取暂降监测点
        List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceInfoClient.getPracticalAllDeviceInfo(deviceInfoParam).getData();
        List<String> lineIndexs;
        int i = 0, generalDeviceListSize = generalDeviceDTOList.size();
        while (i < generalDeviceListSize) {
            List<Object> objectList = new ArrayList<>();
            GeneralDeviceDTO generalDeviceDTO = generalDeviceDTOList.get(i);
            lineIndexs = generalDeviceDTO.getLineIndexes();
            //获取暂降数据
            if (lineIndexs.size() > 0) {
                int tail = 0;
                List<EventHeatDeatilVO> eventdetailList = getContion(deviceInfoParam, lineIndexs);
                if (eventdetailList.size() > 0) {
                    for (int eventNum = 0; eventNum < eventdetailList.size(); eventNum++) {
                        EventHeatMapDetailVO eventHeatMapDetailVO = new EventHeatMapDetailVO();
                        LineDetailVO lineDetailVO = lineFeignClient.getLineSubGdDetail(eventdetailList.get(eventNum).getLineId()).getData();
                        BeanUtil.copyProperties(lineDetailVO, eventHeatMapDetailVO);
                        eventHeatMapDetailVO.setEventNum(eventdetailList.get(eventNum).getCount());
                        tail += eventdetailList.get(eventNum).getCount();
                        eventHeatMapDetailList.add(eventHeatMapDetailVO);
                    }
                    objectList.add(generalDeviceDTO.getName()+"\n("+lineIndexs.size()+")");
                    objectList.add(tail);
                    listObject.add(objectList);
                }
            }
            i++;
        }
        eventHeatMapVO.setAreaValue(listObject);
        eventHeatMapVO.setEventHeatMapValue(eventHeatMapDetailList);
        return eventHeatMapVO;
    }

    @Override
    public EventSeverityVO getEventSeverity(DeviceInfoParam.BusinessParam deviceInfoParam) {
        EventSeverityVO eventSeverityVO = new EventSeverityVO();
        List<EventSeverityValueVO> eventSeverityValueList = new ArrayList<>();
        deviceInfoParam.setServerName(ServerEnum.EVENT.getName());
        List<List<Object>> listObject = new ArrayList<>();
        //获取暂降监测点
        List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceInfoClient.getPracticalAllDeviceInfo(deviceInfoParam).getData();
        List<String> lineIndexs;
        int i = 0, generalDeviceListSize = generalDeviceDTOList.size();
        while (i < generalDeviceListSize) {
            List<Object> objectList = new ArrayList<>();
            GeneralDeviceDTO generalDeviceDTO = generalDeviceDTOList.get(i);
            lineIndexs = generalDeviceDTO.getLineIndexes();
            //获取暂降数据
            if (lineIndexs.size() > 0) {
                int tail = 0;
                EventSeverityValueVO eventSeverityValueVO = new EventSeverityValueVO();
                List<EventHeatDeatilVO> eventdetailList = getContion(deviceInfoParam, lineIndexs);
                if (eventdetailList.size()>0){
                    for (int eventNum = 0; eventNum < eventdetailList.size(); eventNum++) {
                        tail += eventdetailList.get(eventNum).getCount();
                    }
                    eventSeverityValueVO.setAreaName(generalDeviceDTO.getName());
                    eventSeverityValueVO.setLineNum(lineIndexs.size());
                    eventSeverityValueVO.setEventNum(tail);
                    eventSeverityValueList.add(eventSeverityValueVO);
                    objectList.add(generalDeviceDTO.getName()+"\n("+lineIndexs.size()+")");
                    objectList.add(tail);
                    listObject.add(objectList);
                }
            }
            i++;
        }
        eventSeverityVO.setAreaValue(listObject);
        eventSeverityVO.setEventSeverityValue(eventSeverityValueList);
        return eventSeverityVO;
    }


    public List<EventHeatDeatilVO> getContion(DeviceInfoParam.BusinessParam deviceInfoParam, List<String> lineIndexs) {
        //组装sql语句
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("time >= '").append(DateUtil.beginOfDay(DateUtil.parse(deviceInfoParam.getSearchBeginTime()))).append("' and ").append("time <= '").append(DateUtil.endOfDay(DateUtil.parse(deviceInfoParam.getSearchEndTime()))).append("' and ");
        int j = 0;
        //sql语句
        for (String line : lineIndexs) {
            if (j == 0) {
                stringBuilder.append("line_id ='").append(line).append("'");
            } else {
                stringBuilder.append(" or line_id ='").append(line).append("'");
            }
            j++;
        }
        stringBuilder.append(" group by line_id");
        //获取暂降事件
        String sql = "select count(file_flag) from  pqs_eventdetail  where " + stringBuilder.toString();
        QueryResult result = influxDbUtils.query(sql);
        InfluxDBResultMapper influxDBResultMapper = new InfluxDBResultMapper();
        List<EventHeatDeatilVO> eventdetailList = influxDBResultMapper.toPOJO(result, EventHeatDeatilVO.class);
        return eventdetailList;
    }
}
