package com.jiayue.ipfcst.dataexchange.service;

import cn.hutool.core.lang.Console;
import com.jiayue.ipfcst.common.core.exception.BusinessException;
import com.jiayue.ipfcst.common.data.constant.enums.EquipmentTypeEnum;
import com.jiayue.ipfcst.common.data.entity.ProtocolGatherDataPoint;
import com.jiayue.ipfcst.common.data.entity.ProtocolSenderDataPoint;
import com.jiayue.ipfcst.common.data.entity.SendLog;
import com.jiayue.ipfcst.common.data.repository.SendLogRepository;
import com.jiayue.ipfcst.console.service.*;
import com.jiayue.ipfcst.dataexchange.repository.ProtocolSenderDataPointRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 回传日志Service
 *
 * @author 修唯xiuwei
 * @version 3.0
 */
@Service
@Slf4j
public class SendLogService {
  private final SendLogRepository sendLogRepository;
  private final ProtocolSenderDataPointRepository protocolSenderDataPointRepository;
  private final ProtocolGatherDataPointService protocolGatherDataPointService;
  private final ElectricFieldService electricFieldService;
  private final WeatherStationInfoService weatherStationInfoService;
  private final WindTowerInfoService windTowerInfoService;
  private final WindTurbineInfoService windTurbineInfoService;
  private final AGC_AVCInfoService agcAvcInfoService;
  private final BoosterStationInfoService boosterStationInfoService;
  private final InverterInfoService inverterInfoService;

  public SendLogService(SendLogRepository sendLogRepository,
    ProtocolSenderDataPointRepository protocolSenderDataPointRepository,
    ProtocolGatherDataPointService protocolGatherDataPointService, ElectricFieldService electricFieldService,
    WeatherStationInfoService weatherStationInfoService, WindTowerInfoService windTowerInfoService,
    WindTurbineInfoService windTurbineInfoService, AGC_AVCInfoService agcAvcInfoService,
    BoosterStationInfoService boosterStationInfoService, InverterInfoService inverterInfoService) {
    this.sendLogRepository = sendLogRepository;
    this.protocolSenderDataPointRepository = protocolSenderDataPointRepository;
    this.protocolGatherDataPointService = protocolGatherDataPointService;
    this.electricFieldService = electricFieldService;
    this.weatherStationInfoService = weatherStationInfoService;
    this.windTowerInfoService = windTowerInfoService;
    this.windTurbineInfoService = windTurbineInfoService;
    this.agcAvcInfoService = agcAvcInfoService;
    this.boosterStationInfoService = boosterStationInfoService;
    this.inverterInfoService = inverterInfoService;
  }

  /**
   *  获取数据
   * @param startTime     开始时间
   * @param endTime       结束时间
   * @param page          第几页
   * @param size          每页几天数据
   * @return
   */
  public Page getAll(Long startTime, Long endTime, Integer page, Integer size) {
    //分页信息
    Pageable pageable = PageRequest.of(page-1, size); //页码：前端从1开始，jpa从0开始，做个转换
    Page<SendLog> pageDatas = sendLogRepository.findByCreateTimeBetween(new Date(startTime),new Date(endTime),pageable);
    if (log.isDebugEnabled()) {
      log.debug("查询记录数：" + pageDatas.getContent().size());
      log.debug("查询结束!");
    }
    return pageDatas;
  }

  /**
   * 保存
   *
   * @param sendLog 发送日志
   * @return {@link SendLog}
   */
  public SendLog save(SendLog sendLog){
    return sendLogRepository.save(sendLog);
  }

  /**
   *  获取数据
   * @param startTime     开始时间
   * @param endTime       结束时间
   * @param page          第几页
   * @param size          每页几天数据
   * @param tunnelId      通道id
   * @return
   */
  public Page getAllById(Long startTime, Long endTime, Integer page, Integer size , String tunnelId) {
    //分页信息
    Pageable pageable = PageRequest.of(page-1, size); //页码：前端从1开始，jpa从0开始，做个转换
    Page pageDatas = sendLogRepository.findByCreateTimeBetweenAndTunnelId(new Date(startTime),new Date(endTime),tunnelId,pageable);
    if (log.isDebugEnabled()) {
      log.debug("查询记录数：" + pageDatas.getContent().size());
      log.debug("查询结束!");
    }
    return pageDatas;
  }

  /**
  * 详细的回传内容
  */
  public List<Map> getProDataPoint(Long startTime,String tunnelId) throws BusinessException {
    List list = new ArrayList();
    List<Map<String,Object>> list1 = new ArrayList();
    List<Map<String,Object>> list2 = new ArrayList();
//    SendLog sendLog = new SendLog();
//    sendLog.setTunnelId(tunnelId);
//    List<SendLog> sendLogList = sendLogRepository.findAll(Example.of(sendLog));
    Long endTime = startTime + 60000l;
    List<SendLog> sendLogList = sendLogRepository.findByCreateTimeBetweenAndTunnelId(new Date(startTime), new Date(startTime), tunnelId);
    List<ProtocolSenderDataPoint> senderDataPoints = protocolSenderDataPointRepository.findByTunnelId(tunnelId);
    List<ProtocolGatherDataPoint> gatherDataPoints = protocolGatherDataPointService.getAll();
    senderDataPoints.sort(Comparator.comparing(ProtocolSenderDataPoint::getProtocolPointNo));
    if(sendLogList.get(0).getSendLog() == null){
      Map<String, Object> map = new HashMap();
      map.put("name","");
      map.put("info","无数据");
      list.add(map);
    }else{
      String[] s = sendLogList.get(0).getSendLog().split(",");
      for(int i = 0; i<s.length; i++){
        Map<String, Object> map1 = new HashMap();
        Map<String, Object> map2 = new HashMap();
        String name = "";
        if (senderDataPoints.get(i).getGatherPoint() != null) {
          for (int j = 0; j < gatherDataPoints.size(); j++) {
            if (senderDataPoints.get(i).getGatherPoint().equals(gatherDataPoints.get(j).getId())) {
              map1.put("code",gatherDataPoints.get(j).getEquipmentAttribute().getEquipmentType().getCode());
              map1.put("name", formatEqName(gatherDataPoints.get(j).getEquipmentAttribute().getEquipmentType().getCode(), gatherDataPoints.get(j).getEquipmentId()));
              map1.put("info", gatherDataPoints.get(j).getEquipmentAttribute().getExplanation() +":"+s[i]);
              list1.add(map1);
            }
          }
        }else {
          map2.put("code",senderDataPoints.get(i).getForecastForSendAttribute().getForecastType().getCode());
          map2.put("describe",senderDataPoints.get(i).getForecastForSendAttribute().getForecastType().getDescribe());
          map2.put("forecastNode", senderDataPoints.get(i).getForecastForSendAttribute().getForecastNode());
          DecimalFormat df = new DecimalFormat("0.00");
          String value = "";
          String si = new BigDecimal(s[i]).setScale(0, BigDecimal.ROUND_DOWN).toString();
          if(si.length()<3 && si.length() == 2){
            value = "&ensp;"+df.format(new BigDecimal(s[i]));
          }else if(si.length()<3 && si.length() == 1){
            value = "&emsp;"+df.format(new BigDecimal(s[i]));
          }else{
            value = df.format(new BigDecimal(s[i]));
          }
          map2.put("value",value);
          list2.add(map2);
        }
      }
      /*外部接入*/
      if(list1.size()>0){
        for(int i = 0; i<9; i++){
          Map<String, Object> map = new HashMap();
          String info = "";
          int finalK = i;
          List<Map<String, Object>> fileList1 = list1.stream().filter(w -> w.get("code").toString().equals(String.valueOf(finalK))).collect(Collectors.toList());
          if(fileList1.size()>0){
            for(int j = 0;j<fileList1.size(); j++){
              info = info + fileList1.get(j).get("info")+";"+"&emsp;";
            }
            map.put("name",fileList1.get(0).get("name"));
            map.put("info",info);
            list.add(map);
          }
        }
      }
      /*预测生成*/
      if(list2.size()>0){
        for(int i = 0; i<4; i++){
          Map<String, Object> map = new HashMap();
          String info = "";
          int finalI = i;
          List<Map<String, Object>> fileList1 = list2.stream().filter(w -> w.get("code").toString().equals(String.valueOf(finalI))).collect(Collectors.toList());
          if(fileList1.size()>0){
            map.put("name",fileList1.get(0).get("describe"));
            for(int k = 0; k<10; k++){
              int finalK = k;
              String value = "";
              List<Map<String, Object>> fileNodeList = fileList1.stream().filter(w -> w.get("forecastNode").toString().equals(String.valueOf(finalK))).collect(Collectors.toList());
              if(fileNodeList.size()>0){
                String forecastNode = formatForecastName(fileNodeList.get(0).get("code").toString(),fileNodeList.get(0).get("forecastNode").toString());
                for(int j = 0;j<fileNodeList.size(); j++){
                  value = value + fileNodeList.get(j).get("value") + ",";
                }
                info = info + forecastNode + ":" + value+"<br/>";
              }
            }
            map.put("info",info);
            list.add(map);
          }
        }
      }
    }
    return list;
  }

  public String formatEqName(Integer type,Integer id) throws BusinessException {
    String name = "";
    EquipmentTypeEnum equipmentTypeEnum = null;
    equipmentTypeEnum = EquipmentTypeEnum.valueOf(type);
    switch (equipmentTypeEnum) {
      case POWERSTATION:
        name = electricFieldService.get().getName();
        break;
      case WEATHERSTATION:
        name = weatherStationInfoService.get(id).getName();
        break;
      case INVERTER:
        name = inverterInfoService.get(id).getName();
        break;
      case WINDTOWER:
        name = windTowerInfoService.get(id).getName();
        break;
      case WINDTURBINE:
        name = windTurbineInfoService.get(id).getName();
        break;
      case BOOSTERSTATION:
        name = boosterStationInfoService.get(id).getName();
        break;
      case AGC_AVC:
        name = inverterInfoService.get(id).getName();
        break;
    }
    return name;
  }

  public String formatForecastName(String code, String node){
    String forecastNode = "";
    if(code.equals("2") || code.equals("3")){
      switch (Integer.parseInt(node)){
        case 0: forecastNode = "第一小时";
          break;
        case 1: forecastNode = "第二小时";
          break;
        case 2: forecastNode = "第三小时";
          break;
        case 3: forecastNode = "第四小时";
          break;
      }
    } else {
      forecastNode = "第" + (Integer.parseInt(node)+1) + "天";
    }
    return forecastNode;
  }
}
