package com.jiayue.ipfcst.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.jiayue.ipfcst.common.core.exception.BusinessException;
import com.jiayue.ipfcst.common.data.constant.enums.AlarmTypeEnum;
import com.jiayue.ipfcst.common.data.entity.*;
import com.jiayue.ipfcst.common.data.repository.*;
import com.jiayue.ipfcst.common.data.service.BaseService;
import com.jiayue.ipfcst.dto.ChannelStatusDto;
import com.jiayue.ipfcst.dto.UploadRateDto;
import com.jiayue.ipfcst.util.GzipUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.IOException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 二维码生成业务层
 *
 * @author yh
 * @version 1.0
 * @since 2020/8/5 16:02
 */
@Service
@Slf4j
public class QrCodeService extends BaseService {
  private final PowerStationStatusDataRepository powerStationStatusDataRepository;

  private final WeatherStationStatusDataRepository weatherStationStatusDataRepository;
  private final WindTowerStatusDataRepository windTowerStatusDataRepository;
  private final FileAnalysisRecordRepository fileAnalysisRecordRepository;
  private final DashboardService dashboardService;
  private final static String IMAGE_TYPE = "jpg";
  private final ForecastPowerUltraShortTermHisRepository forecastPowerUltraShortTermHisRepository;
  private final WindTurbineInfoRepository windTurbineInfoRepository;
  private final WindTowerInfoService windTowerInfoService;
  private final WindTurbineStatusDataRepository windTurbineStatusDataRepository;
  private final SysParameterRepository sysParameterRepository;

  @Autowired
  public QrCodeService(PowerStationStatusDataRepository powerStationStatusDataRepository,
                       WeatherStationStatusDataRepository weatherStationStatusDataRepository,
                       WindTowerStatusDataRepository windTowerStatusDataRepository,
                       FileAnalysisRecordRepository fileAnalysisRecordRepository,
                       DashboardService dashboardService, ForecastPowerUltraShortTermHisRepository forecastPowerUltraShortTermHisRepository, WindTurbineInfoRepository windTurbineInfoRepository, WindTowerInfoService windTowerInfoService, WindTurbineStatusDataRepository windTurbineStatusDataRepository, SysParameterRepository sysParameterRepository) {
    this.powerStationStatusDataRepository = powerStationStatusDataRepository;
    this.weatherStationStatusDataRepository = weatherStationStatusDataRepository;
    this.windTowerStatusDataRepository = windTowerStatusDataRepository;
    this.fileAnalysisRecordRepository = fileAnalysisRecordRepository;
    this.dashboardService = dashboardService;
    this.forecastPowerUltraShortTermHisRepository = forecastPowerUltraShortTermHisRepository;
    this.windTurbineInfoRepository = windTurbineInfoRepository;
    this.windTowerInfoService = windTowerInfoService;
    this.windTurbineStatusDataRepository = windTurbineStatusDataRepository;
    this.sysParameterRepository = sysParameterRepository;
  }

  /**
   * 实际功率二维码内容生成
   *
   * @param startTime 开始时间
   * @param endTime   结束时间
   * @return 二维码生成内容集
   * @throws IOException       io异常
   * @throws BusinessException 业务异常
   */
  public List<String> generateRealPowerCodeContent(Long startTime, Long endTime) throws IOException, BusinessException {

    ElectricField electricField = this.getElectricField();
    long timeStep = 900000L;
    if (startTime % timeStep != 0) {
      startTime = startTime - (startTime % timeStep) + timeStep;
    }
    String content = electricField.getStationCode() + "|" + startTime.toString() + "|";

    List<PowerStationStatusData> pList = powerStationStatusDataRepository.findByTimeBetween(new Date(startTime), new Date(endTime));
    for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + timeStep) {
      long finalTime = stepTime;
      List<PowerStationStatusData> pFilter = pList.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
      if (pFilter != null && pFilter.size() > 0) {
        content = content + pFilter.get(0).getRealValue().setScale(2, BigDecimal.ROUND_HALF_UP).toString() + "|";
      } else {
        content = content + "-0.99|";
      }
    }

    int packSize = 100;


    int qr_code_days = getTranSysParameter("QR_CODE_SIZE", "8");


    packSize = packSize * qr_code_days;

    List<String> qrCodeContents = GzipUtil.pubZipList(content, packSize);
    List<String> result = new ArrayList<>();
    String taskNo = getTaskNo(electricField);
    for (int i = 0; i < qrCodeContents.size(); i++) {
      JSONObject jsonObject = new JSONObject();
      jsonObject.putOnce("taskNo", taskNo);
      jsonObject.putOnce("taskType", "stationData-rp");
      jsonObject.putOnce("partNo", i + 1);
      jsonObject.putOnce("partTotal", qrCodeContents.size());
      jsonObject.putOnce("data", qrCodeContents.get(i));
      result.add(i, jsonObject.toString());
    }

    return result;
  }


  /**
   * 环境数据二维码内容生成
   *
   * @param startTime 开始时间
   * @param endTime   结束时间
   * @param no        设备id
   * @param attr      属性
   * @param eqType    设备类型
   * @return 二维码生成内容集
   * @throws IOException            IO异常
   * @throws BusinessException      业务异常
   * @throws NoSuchFieldException   反射异常
   * @throws IllegalAccessException 反射异常
   */
  public List<String> generateEnvCodeContent(Long startTime, Long endTime, Integer no, String attr, String eqType) throws IOException, BusinessException, NoSuchFieldException, IllegalAccessException {

    ElectricField electricField = this.getElectricField();
    long timeStep = 900000L;
    if (startTime % timeStep != 0) {
      startTime = startTime - (startTime % timeStep) + timeStep;
    }

    String content = electricField.getStationCode() + "-" + no + "|" + attr + "|" + startTime.toString() + "|";

    if (eqType.equals("WEATHERSTATION")) {
      List<WeatherStationStatusData> wlist = weatherStationStatusDataRepository.findByTimeBetweenAndEquipmentNo(new Date(startTime), new Date(endTime), no);
      List<WeatherStationStatusData> collect = wlist.stream().filter(w -> w.getIsGenerated().equals(false)).collect(Collectors.toList());
      for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + timeStep) {
        long finalTime = stepTime;
        List<WeatherStationStatusData> wFilter = collect.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
        if (wFilter != null && wFilter.size() > 0) {
          WeatherStationStatusData w = wFilter.get(0);
          Field field = w.getClass().getDeclaredField(attr);
          field.setAccessible(true);
          BigDecimal value = (BigDecimal) field.get(w);
          content = content + value.toString() + "|";
        } else {
          content = content + "-99|";
        }
      }
    } else {
      List<WindTowerStatusData> wlist = windTowerStatusDataRepository.findByEquipmentNoAndTimeBetween(no, new Date(startTime), new Date(endTime));
      List<WindTowerStatusData> collect = wlist.stream().filter(w -> w.getIsGenerated().equals(false)).collect(Collectors.toList());
      for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + timeStep) {
        long finalTime = stepTime;
        List<WindTowerStatusData> wFilter = collect.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
        if (wFilter != null && wFilter.size() > 0) {
          WindTowerStatusData w = wFilter.get(0);
          Field field = w.getClass().getDeclaredField(attr);
          field.setAccessible(true);
          BigDecimal value = (BigDecimal) field.get(w);
          content = content + value.toString() + "|";
        } else {
          content = content + "-99|";
        }
      }
    }

    List<String> qrCodeContents = GzipUtil.zipList(content);
    List<String> result = new ArrayList<>();
    String taskNo = getTaskNo(electricField);
    for (int i = 0; i < qrCodeContents.size(); i++) {
      JSONObject jsonObject = new JSONObject();
      jsonObject.putOnce("taskNo", taskNo);
      jsonObject.putOnce("taskType", "stationData-env");
      jsonObject.putOnce("partNo", i + 1);
      jsonObject.putOnce("partTotal", qrCodeContents.size());
      jsonObject.putOnce("data", qrCodeContents.get(i));
      result.add(i, jsonObject.toString());
    }

    return result;

  }

  /**
   * 可用二维码内容生成
   *
   * @param startTime 开始时间
   * @param endTime   结束时间
   * @return 二维码生成内容集
   * @throws IOException            IO异常
   * @throws BusinessException      业务异常
   * @throws NoSuchFieldException   反射异常
   * @throws IllegalAccessException 反射异常
   */
  public List<String> generateReportShortTermContent(Long startTime, Long endTime) throws IOException, BusinessException {

    ElectricField electricField = this.getElectricField();
    long timeStep = 900000L;
    if (startTime % timeStep != 0) {
      startTime = startTime - (startTime % timeStep) + timeStep;
    }
    String content = electricField.getStationCode() + "|" + startTime.toString() + "|";

    List<PowerStationStatusData> pList = powerStationStatusDataRepository.findByTimeBetween(new Date(startTime), new Date(endTime));
    for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + timeStep) {
      long finalTime = stepTime;
      List<PowerStationStatusData> pFilter = pList.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
      if (pFilter != null && pFilter.size() > 0) {
        content = content + pFilter.get(0).getAbleValue().setScale(2, BigDecimal.ROUND_HALF_UP).toString() + "|";
      } else {
        content = content + "-0.99|";
      }
    }

    int packSize = 100;


    int qr_code_days = getTranSysParameter("QR_CODE_SIZE", "8");


    packSize = packSize * qr_code_days;

    List<String> qrCodeContents = GzipUtil.pubZipList(content, packSize);
    List<String> result = new ArrayList<>();
    String taskNo = getTaskNo(electricField);
    for (int i = 0; i < qrCodeContents.size(); i++) {
      JSONObject jsonObject = new JSONObject();
      jsonObject.putOnce("taskNo", taskNo);
      jsonObject.putOnce("taskType", "stationData-ap");
      jsonObject.putOnce("partNo", i + 1);
      jsonObject.putOnce("partTotal", qrCodeContents.size());
      jsonObject.putOnce("data", qrCodeContents.get(i));
      result.add(i, jsonObject.toString());
    }

    return result;
  }

  /**
   * 上报短期二维码内容生成
   *
   * @param startTime 开始时间
   * @param endTime   结束时间
   * @return 二维码生成内容集
   * @throws IOException            IO异常
   * @throws BusinessException      业务异常
   * @throws NoSuchFieldException   反射异常
   * @throws IllegalAccessException 反射异常
   */
  public List<String> generateShortTermContent(Long startTime, Long endTime, Integer ago) throws IOException, BusinessException {

    ElectricField electricField = this.getElectricField();
    long timeStep = 900000L;
    if (startTime % timeStep != 0) {
      startTime = startTime - (startTime % timeStep) + timeStep;
    }
    String content = electricField.getStationCode() + "|" + startTime.toString() + "|";


    List<ForecastPowerUltraShortTermHis> pList = forecastPowerUltraShortTermHisRepository.findByForecastTimeBetweenAndForecastHowLongAgo(startTime, endTime, ago);
    for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + timeStep) {
      long finalTime = stepTime;
      List<ForecastPowerUltraShortTermHis> pFilter = pList.stream().filter(p -> p.getForecastTime() == finalTime).collect(Collectors.toList());
      if (pFilter != null && pFilter.size() > 0) {
        content = content + pFilter.get(0).getAbleValue().setScale(2, BigDecimal.ROUND_HALF_UP).toString() + "|";
      } else {
        content = content + "-0.99|";
      }
    }

    int packSize = 100;


    int qr_code_days = getTranSysParameter("QR_CODE_SIZE", "8");


    packSize = packSize * qr_code_days;

    List<String> qrCodeContents1 = GzipUtil.pubZipList(content, packSize);
    List<String> result = new ArrayList<>();
    String taskNo = getTaskNo(electricField);
    for (int i = 0; i < qrCodeContents1.size(); i++) {
      JSONObject jsonObject = new JSONObject();
      jsonObject.putOnce("taskNo", taskNo);
      jsonObject.putOnce("taskType", "stationData-st");
      jsonObject.putOnce("partNo", i + 1);
      jsonObject.putOnce("partTotal", qrCodeContents1.size());
      jsonObject.putOnce("data", qrCodeContents1.get(i));
      result.add(i, jsonObject.toString());
    }

    return result;
  }

  /**
   * 首页实际功率二维码生成
   *
   * @param response 二维码回写流
   * @throws IOException io异常
   */
  public void generateRealPowerCode(HttpServletResponse response) throws IOException, BusinessException {

    ElectricField electricField = this.getElectricField();
    long timeStep = 900000L;
    long startTime = DateUtil.offsetDay(DateUtil.beginOfDay(DateTime.now()), -1).getTime();
    long endTime = DateUtil.beginOfDay(DateTime.now()).getTime() - 900000L;
    String contents = "";
    //----------------------------环境数据-----------------------------------
    if (electricField.getElectricFieldTypeEnum().getCode() == 1) {
      //光场站
      // 0无意义 1是设备ID 0是总辐射
      String sys = super.getSysParameter("EN_QR_CODE", "0,1,0");
      String[] sysData = sys.split(",");
      List<WeatherStationStatusData> wlist = weatherStationStatusDataRepository.findByTimeBetweenAndEquipmentNo(new Date(startTime), new Date(endTime), Integer.parseInt(sysData[1]));
      List<WeatherStationStatusData> collect = wlist.stream().filter(w -> w.getIsGenerated().equals(false)).collect(Collectors.toList());
      //总辐射
      if (sysData[2].equals("0")) {
        for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + timeStep) {
          long finalTime = stepTime;
          List<WeatherStationStatusData> wFilter = collect.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
          if (wFilter != null && wFilter.size() > 0) {
            contents = contents + wFilter.get(0).getGlobalR().toString() + "|";
          } else {
            contents = contents + "-0.99|";
          }
        }
      }
      //倾斜辐射
      if (sysData[2].equals("1")) {
        for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + timeStep) {
          long finalTime = stepTime;
          List<WeatherStationStatusData> wFilter = collect.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
          if (wFilter != null && wFilter.size() > 0) {
            contents = contents + wFilter.get(0).getObliqueR().toString() + "|";
          } else {
            contents = contents + "-0.99|";
          }
        }
      }
    } else {
      //风场站
      // 0为测风塔 1是设备ID 70是70米风速
      String sys = super.getSysParameter("EN_QR_CODE", "0,1,70");
      String[] sysData = sys.split(",");
      if (sysData[0].equals("0")) {
        //测风塔
        List<WindTowerStatusData> wlist = windTowerStatusDataRepository.findByEquipmentNoAndTimeBetween(Integer.parseInt(sysData[1]), new Date(startTime), new Date(endTime));
        List<WindTowerStatusData> collect = wlist.stream().filter(w -> w.getIsGenerated().equals(false)).collect(Collectors.toList());
        for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + timeStep) {
          long finalTime = stepTime;
          List<WindTowerStatusData> wFilter = collect.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
          if (wFilter != null && wFilter.size() > 0) {
            try {
              switch (sysData[2]) {
                case "10":
                  contents = contents + wFilter.get(0).getWsInst10().toString() + "|";
                  break;
                case "30":
                  contents = contents + wFilter.get(0).getWsInst30().toString() + "|";
                  break;
                case "50":
                  contents = contents + wFilter.get(0).getWsInst50().toString() + "|";
                  break;
                case "60":
                  contents = contents + wFilter.get(0).getWsInst60().toString() + "|";
                  break;
                case "70":
                  contents = contents + wFilter.get(0).getWsInst70().toString() + "|";
                  break;
                case "80":
                  contents = contents + wFilter.get(0).getWsInst80().toString() + "|";
                  break;
                case "90":
                  contents = contents + wFilter.get(0).getWsInst90().toString() + "|";
                  break;
                case "100":
                  contents = contents + wFilter.get(0).getWsInst100().toString() + "|";
                  break;
                case "110":
                  contents = contents + wFilter.get(0).getWsInst110().toString() + "|";
                  break;
                case "120":
                  contents = contents + wFilter.get(0).getWsInst120().toString() + "|";
                  break;
                default:
                  contents = contents + "-0.99|";
                  break;
              }
            } catch (Exception e) {
              contents = contents + "-0.99|";
            }
          } else {
            contents = contents + "-0.99|";
          }
        }
      } else if (sysData[0].equals("1")) {
        //风机样板机
        List<WindTurbineInfo> windTurbineInfoList = windTurbineInfoRepository.findAllByOrderByIdAsc();
        List<WindTurbineInfo> collect = windTurbineInfoList.stream().filter(w -> w.getSample().equals(true)).collect(Collectors.toList());

        for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + timeStep) {
          long finalTime = stepTime;
          BigDecimal countWs = new BigDecimal(0);
          try {
            for (int i = 0; i < collect.size(); i++) {
              List<WindTurbineStatusData> wlist = windTurbineStatusDataRepository.findByTimeBetweenAndEquipmentNo(new Date(startTime), new Date(endTime), collect.get(i).getId());
              List<WindTurbineStatusData> wFilter = wlist.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
              if (wFilter != null && wFilter.size() > 0) {
                countWs = countWs.add(wFilter.get(0).getWs());
              } else {
                countWs = countWs.add(new BigDecimal(0));
              }
            }
            contents = contents + countWs.divide(BigDecimal.valueOf(collect.size()), 2, BigDecimal.ROUND_HALF_UP).toString() + "|";
          } catch (Exception e) {
            contents = contents + "-0.99|";
          }
        }
      } else {
        //全场风机风速
        List<WindTurbineInfo> windTurbineInfoList = windTurbineInfoRepository.findAllByOrderByIdAsc();
        for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + timeStep) {
          long finalTime = stepTime;
          BigDecimal countWs = new BigDecimal(0);
          try {
            for (int i = 0; i < windTurbineInfoList.size(); i++) {
              List<WindTurbineStatusData> wlist = windTurbineStatusDataRepository.findByTimeBetweenAndEquipmentNo(new Date(startTime), new Date(endTime), windTurbineInfoList.get(i).getId());
              List<WindTurbineStatusData> wFilter = wlist.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
              if (wFilter != null && wFilter.size() > 0) {
                countWs = countWs.add(wFilter.get(0).getWs());
              } else {
                countWs = countWs.add(new BigDecimal(0));
              }
            }
            contents = contents + countWs.divide(BigDecimal.valueOf(windTurbineInfoList.size()), 2, BigDecimal.ROUND_HALF_UP).toString() + "|";
          } catch (Exception e) {
            contents = contents + "-0.99|";
          }
        }
      }
    }
    //----------------------------实际功率-----------------------------------
    String content = electricField.getStationCode() + "|" + startTime + "|rp|";

    List<PowerStationStatusData> pList = powerStationStatusDataRepository.findByTimeBetween(new Date(startTime), new Date(endTime));
    for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + timeStep) {
      long finalTime = stepTime;
      List<PowerStationStatusData> pFilter = pList.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
      if (pFilter != null && pFilter.size() > 0) {
        content = content + pFilter.get(0).getRealValue().setScale(2, BigDecimal.ROUND_HALF_UP).toString() + "|";
      } else {
        content = content + "-0.99|";
      }
    }

    String zipContent = GzipUtil.zip(content + contents).replace("\r\n", "");

    String taskNo = getTaskNo(electricField);

    JSONObject jsonObject = new JSONObject();
    jsonObject.putOnce("taskNo", taskNo);
    jsonObject.putOnce("taskType", "stationData-rp");
    jsonObject.putOnce("partNo", 1);
    jsonObject.putOnce("partTotal", 1);
    jsonObject.putOnce("data", zipContent);

    String qrCodeContent = jsonObject.toString();

    QrConfig config = this.getQrConfig(500, 500, Color.black, Color.white);

    ServletOutputStream out = response.getOutputStream();

    QrCodeUtil.generate(qrCodeContent, config, IMAGE_TYPE, out);
  }

  /**
   * 首页运行状态二维码生成
   *
   * @param response 二维码回写流
   * @throws IOException io异常
   */
  public void generateRunningStatusCode(HttpServletResponse response) throws IOException, BusinessException {

    ElectricField electricField = this.getElectricField();
    long startTime = DateUtil.beginOfDay(DateTime.now()).getTime();
    long endTime = DateTime.now().getTime();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    JSONObject resultJson = JSONUtil.createObj();
    resultJson.putOnce("code", electricField.getStationCode());
    resultJson.putOnce("time", sdf.format(new Date(endTime)));
    int status = 1;
    //文件解析，如果当前时间没有nwp或dq  或 当前nwp和dq的最后一条记录解析失败 那么 状态异常（2020.11.16 跟徐哥讨论结果）
    JSONObject fileAnalysisJson = JSONUtil.createObj();
    List<FileAnalysisRecord> fList = fileAnalysisRecordRepository.findByCreateTimeBetween(new Date(startTime), new Date(endTime));

    List<FileAnalysisRecord> dq = fList.stream().filter(f -> f.getFileType().equals("DQ")).collect(Collectors.toList());
    List<FileAnalysisRecord> nwp = fList.stream().filter(f -> f.getFileType().equals("NWP")).collect(Collectors.toList());
    List<FileAnalysisRecord> upJson = fList.stream().filter(f -> f.getFileType().equals("UP")).collect(Collectors.toList());
    JSONArray dqFileAnalysisArray = JSONUtil.createArray();
    JSONArray nwpFileAnalysisArray = JSONUtil.createArray();
    JSONArray upFileAnalysisArray = JSONUtil.createArray();
    if (dq.size() > 0) {
      dq.sort(Comparator.comparing(FileAnalysisRecord::getCreateTime));
      for (FileAnalysisRecord f : dq) {
        JSONObject jb = JSONUtil.createObj();
        jb.putOnce("name", f.getFileTitle());
        jb.putOnce("time", sdf.format(f.getCreateTime()));
        jb.putOnce("status", f.getFileStatus());
        dqFileAnalysisArray.put(jb);
      }
      String dqFileStatus = dq.get(dq.size() - 1).getFileStatus();
      if (dqFileStatus.equals("0")) {
        status = 0;
      }
    } else {
      status = 0;
    }
    fileAnalysisJson.putOnce("dq", dqFileAnalysisArray);

    if (nwp.size() > 0) {
      nwp.sort(Comparator.comparing(FileAnalysisRecord::getCreateTime));
      for (FileAnalysisRecord f : nwp) {
        JSONObject jb = JSONUtil.createObj();
        jb.putOnce("name", f.getFileTitle());
        jb.putOnce("time", sdf.format(f.getCreateTime()));
        jb.putOnce("status", f.getFileStatus());
        nwpFileAnalysisArray.put(jb);
      }
      String nwpFileStatus = nwp.get(nwp.size() - 1).getFileStatus();
      if (nwpFileStatus.equals("0")) {
        status = 0;
      }
    } else {
      status = 0;
    }
    fileAnalysisJson.putOnce("nwp", nwpFileAnalysisArray);
    //up不用判断是否解析成功
    upJson.sort(Comparator.comparing(FileAnalysisRecord::getCreateTime));
    for (FileAnalysisRecord f : upJson) {
      JSONObject jb = JSONUtil.createObj();
      jb.putOnce("name", f.getFileTitle());
      jb.putOnce("time", sdf.format(f.getCreateTime()));
      jb.putOnce("status", f.getFileStatus());
      upFileAnalysisArray.put(jb);
    }
    fileAnalysisJson.putOnce("up", upFileAnalysisArray);

    resultJson.putOnce("fileAnalysis", fileAnalysisJson);


    //通道状态
    Map channelStatus = dashboardService.getChannelStatus();
    JSONObject channelStatusJson = JSONUtil.createObj();
    for (Object o : channelStatus.keySet()) {
      String key = (String) o;
      if (!key.equals("analysisList")) {
        List<ChannelStatusDto> cList = (List<ChannelStatusDto>) channelStatus.get(key);
        JSONArray channelStatusArray = JSONUtil.createArray();
        for (ChannelStatusDto c : cList) {
          JSONObject channelStatusInfo = JSONUtil.createObj();
          channelStatusInfo.putOnce("name", c.getChannelName());
          channelStatusInfo.putOnce("status", c.getChannelStatus());
          //当状态不是0（非正常）时进行判断通道是否是正常 不正常将status置成0(非正常)，正常就置成1（正常），
          // 如果状态已经 =0（不正常状态）就不需要再判断通道了
          if (status != 0) {
            status = c.getChannelStatus().equals("0") ? 0 : 1;
          }
          channelStatusArray.add(channelStatusInfo);
        }
        channelStatusJson.putOnce(key, channelStatusArray);
      }

    }

    resultJson.putOnce("channelStatus", channelStatusJson);

    //上报率
    Map uploadFileInfo = dashboardService.getUploadFileInfo();
    JSONObject uploadFileInfoJson = JSONUtil.createObj();
    List uploadObjectRateList = (List) uploadFileInfo.get("uploadObjectRateList");

    for (Object o : uploadObjectRateList) {
      List uploadRateList = (List) o;
      JSONArray uploadFileInfoArray = JSONUtil.createArray();
      String key = "";
      for (Object b : uploadRateList) {
        UploadRateDto uploadRateDto = (UploadRateDto) b;
        JSONObject uploadFile = JSONUtil.createObj();
        uploadFile.putOnce("type", uploadRateDto.getUploadTypeName());
        uploadFile.putOnce("rate", uploadRateDto.getUploadRate());
        if (status != 0) {

          //status = uploadRateDto.getUploadRate().equals("100%") ? 1 : 0;
          if (!uploadRateDto.getUploadRate().equals("100%") && !uploadRateDto.getUploadRate().equals("未到时间")) {
            status = 0;
          }
        }
        uploadFileInfoArray.put(uploadFile);
        key = uploadRateDto.getUploadObjectName();
      }
      uploadFileInfoJson.putOnce(key, uploadFileInfoArray);
    }

    resultJson.putOnce("uploadFile", uploadFileInfoJson);


    //通道断开
    List<ChannelDisconLog> channelDisconLog = dashboardService.getChannelDisconLog();

    String qcl = super.getSysParameter("QRCode_ChannelLog", "5");
    int length = 5;
    try {
      length = Integer.valueOf(qcl).intValue();
    } catch (Exception e) {
      log.warn("QRCode_ChannelLog参数无法转为数字类型，默认5");
    }


    if (channelDisconLog.size() > length) {
      channelDisconLog = channelDisconLog.subList(0, length);
    }
    JSONArray channelDisconLogArray = JSONUtil.createArray();
    for (ChannelDisconLog c : channelDisconLog) {
      JSONObject channelDiscon = JSONUtil.createObj();
      if (c.getDisconnectTime() != null) {
        channelDiscon.putOnce("disconnectTime", sdf.format(new Date(c.getDisconnectTime())));
      } else {
        channelDiscon.putOnce("disconnectTime", "空");
      }

      if (c.getReconnectTime() != null) {
        channelDiscon.putOnce("reconnectTime", sdf.format(new Date(c.getReconnectTime())));
      } else {
        channelDiscon.putOnce("reconnectTime", "空");
      }

      channelDiscon.putOnce("name", c.getChannelName());
      channelDisconLogArray.put(channelDiscon);
    }

    resultJson.putOnce("channelDisconLog", channelDisconLogArray);

    resultJson.putOnce("status", status);

    System.out.println(resultJson);

    String zipContent = GzipUtil.zip(resultJson.toString()).replace("\r\n", "");

    String taskNo = getTaskNo(electricField);

    JSONObject jsonObject = new JSONObject();
    jsonObject.putOnce("taskNo", taskNo);
    jsonObject.putOnce("taskType", "stationData-status");
    jsonObject.putOnce("partNo", 1);
    jsonObject.putOnce("partTotal", 1);
    jsonObject.putOnce("data", zipContent);

    String qrCodeContent = jsonObject.toString();

    QrConfig config = this.getQrConfig(500, 500, Color.black, Color.white);

    ServletOutputStream out = response.getOutputStream();

    QrCodeUtil.generate(qrCodeContent, config, IMAGE_TYPE, out);

  }

  public void statusRunningAnalysis(String json) {

    JSONObject jsonObject = JSONUtil.parseObj(json);
    //1.获取场站编码
    String eCode = jsonObject.get("code").toString();
    System.out.println("1.电站标识:" + eCode);
    //2.获取生成时间
    System.out.println("2.生成时间:" + jsonObject.get("time"));
    //3.获取文件解析
    JSONObject fileAnalysisJson = (JSONObject) jsonObject.get("fileAnalysis");

    //短期解析
    JSONArray dqJson = (JSONArray) fileAnalysisJson.get("dq");
    if (dqJson.size() > 0) {
      for (Object b : dqJson) {
        JSONObject j = (JSONObject) b;
        String status = j.get("status").equals("0") ? "未解析" : "解析";

        System.out.println("3.短期解析=> 名称:" + j.get("name") + " 状态:" + status);
      }
    } else {
      System.out.println("3.短期解析=> 无短期解析记录");
    }

    //nwp解析
    JSONArray nwpJson = (JSONArray) fileAnalysisJson.get("nwp");
    if (nwpJson.size() > 0) {
      for (Object b : nwpJson) {
        JSONObject j = (JSONObject) b;
        String status = j.get("status").equals("0") ? "未解析" : "解析";
        System.out.println("3.nwp解析=> 名称:" + j.get("name") + " 状态:" + status);
      }
    } else {
      System.out.println("3.nwp解析=> 无nwp解析记录");
    }

    //up解析
    JSONArray upJson = (JSONArray) fileAnalysisJson.get("up");
    if (upJson.size() > 0) {
      for (Object b : upJson) {
        JSONObject j = (JSONObject) b;
        String status = j.get("status").equals("0") ? "未解析" : "解析";
        System.out.println("3.up解析=> 名称:" + j.get("name") + " 状态:" + status);
      }
    } else {
      System.out.println("3.up解析=> 无up解析记录");
    }


    //4.通道状态
    JSONObject channelStatusJson = (JSONObject) jsonObject.get("channelStatus");
    //上报类型通道
    JSONArray uploadList = (JSONArray) channelStatusJson.get("uploadList");
    //回传类型通道
    JSONArray callBackList = (JSONArray) channelStatusJson.get("callBackList");
    //采集类型通道
    JSONArray dataexchangeList = (JSONArray) channelStatusJson.get("dataexchangeList");

    if (uploadList != null && uploadList.size() > 0) {
      System.out.println("4.上报对象通道状态:");
      for (int i = 0; i < uploadList.size(); i++) {
        JSONObject j = (JSONObject) uploadList.get(i);
        System.out.println("对象通道:" + j.get("name") + ";  状态:" + j.get("status"));
      }
    } else {
      System.out.println("4.无上报对象通道");
    }

    if (callBackList != null && callBackList.size() > 0) {
      System.out.println("4.回传对象通道状态:");
      for (int i = 0; i < callBackList.size(); i++) {
        JSONObject j = (JSONObject) callBackList.get(i);
        System.out.println("对象通道:" + j.get("name") + ";  状态:" + j.get("status"));
      }
    } else {
      System.out.println("4.无回传对象通道");
    }

    if (dataexchangeList != null && dataexchangeList.size() > 0) {
      System.out.println("4.采集对象通道状态:");
      for (int i = 0; i < dataexchangeList.size(); i++) {
        JSONObject j = (JSONObject) dataexchangeList.get(i);
        System.out.println("对象通道:" + j.get("name") + ";  状态:" + j.get("status"));
      }
    } else {
      System.out.println("4.无采集对象通道");
    }

    //5.上报率
    JSONObject uploadFileJson = (JSONObject) jsonObject.get("uploadFile");
    if (uploadFileJson != null && uploadFileJson.keySet().size() > 0) {
      for (String str : uploadFileJson.keySet()) {
        JSONArray j = (JSONArray) uploadFileJson.get(str);
        if (j != null && j.size() > 0) {
          System.out.println("5.上报率通道名称:" + str);
          for (int i = 0; i < j.size(); i++) {
            JSONObject o = (JSONObject) j.get(i);
            System.out.println("上报率文件:" + o.get("type") + "; 上报率:" + o.get("rate"));
          }
        } else {
          System.out.println("上报率通道名称: " + str + " 下无上报文件类型");
        }
      }
    } else {
      System.out.println("5.无上报率对象");
    }

    //6.通道断开日志
    JSONArray channelDisconLogJson = (JSONArray) jsonObject.get("channelDisconLog");
    if (channelDisconLogJson.size() > 0) {
      for (int i = 0; i < channelDisconLogJson.size(); i++) {
        JSONObject j = (JSONObject) channelDisconLogJson.get(i);
        System.out.println("6.通道名称:" + j.get("name") + "; 断开时间:" + j.get("disconnectTime") + "; 重连时间:" + j.get("reconnectTime"));
      }
    } else {
      System.out.println("6.无断开日志");
    }


  }

  /**
   * 获取taskNo编号
   *
   * @param electricField 场站对象
   * @return 编号
   */

  private String getTaskNo(ElectricField electricField) {
    Date date = DateUtil.date();
    return electricField.getStationCode() + DateUtil.format(date, "yyMMddHHmmss");
  }


  /**
   * 首页超短期二维码生成
   *
   * @param response 二维码回写流
   * @throws IOException io异常
   */
  public void generateForecastUltraShortCode(HttpServletResponse response) throws IOException, BusinessException {

    ElectricField electricField = this.getElectricField();
    long timeStep = 900000L;
    long startTime = DateUtil.offsetDay(DateUtil.beginOfDay(DateTime.now()), -1).getTime();
    long endTime = DateUtil.beginOfDay(DateTime.now()).getTime() - 900000L;
    String content = electricField.getStationCode() + "|" + startTime + "|";
    String contents = "";
    List<ForecastPowerUltraShortTermHis> ultraShortTermHisList;
    String cst = super.getSysParameter("cst_kh_point", "1");
    //是否平均值， 0为平均值 1为点位置
    String sfpjz = super.getSysParameter("sfpjz", "1");
    if (sfpjz.equals("0")) {
      ultraShortTermHisList = forecastPowerUltraShortTermHisRepository.findByForecastTimeBetween(startTime, endTime);
      for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + timeStep) {
        //短期*系数
        BigDecimal agv = new BigDecimal(0);
        //差值
        BigDecimal agvs = new BigDecimal(0);
        long finalTime = stepTime;
        List<ForecastPowerUltraShortTermHis> pFilter = ultraShortTermHisList.stream().filter(p -> p.getForecastTime() == finalTime).collect(Collectors.toList());
        if (pFilter != null && pFilter.size() > 0) {
          for (ForecastPowerUltraShortTermHis forecastPowerUltraShortTermHis : pFilter) {
            agv = agv.add(forecastPowerUltraShortTermHis.getCoefficientValue());
            agvs = agvs.add(forecastPowerUltraShortTermHis.getDifferenceValue());
          }
          content = content + agv.divide(new BigDecimal(pFilter.size()), 2, BigDecimal.ROUND_HALF_UP) + "|";
          contents = contents + agvs.divide(new BigDecimal(pFilter.size()), 2, BigDecimal.ROUND_HALF_UP) + "|";
        } else {
          content = content + "-0.99|";
          contents = contents + "-0.99|";
        }
      }
    } else {
      ultraShortTermHisList = forecastPowerUltraShortTermHisRepository.findByForecastTimeBetweenAndForecastHowLongAgo(startTime, endTime, Integer.parseInt(cst));
      for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + timeStep) {
        long finalTime = stepTime;
        List<ForecastPowerUltraShortTermHis> pFilter = ultraShortTermHisList.stream().filter(p -> p.getForecastTime() == finalTime).collect(Collectors.toList());
        if (pFilter != null && pFilter.size() > 0) {
          content = content + pFilter.get(0).getCoefficientValue().setScale(2, BigDecimal.ROUND_HALF_UP).toString() + "|";
          contents = contents + pFilter.get(0).getDifferenceValue().setScale(2, BigDecimal.ROUND_HALF_UP).toString() + "|";
        } else {
          content = content + "-0.99|";
          contents = contents + "-0.99|";
        }
      }
    }

    String zipContent = GzipUtil.zip(content + contents).replace("\r\n", "");

    String taskNo = getTaskNo(electricField);
    JSONObject jsonObject = new JSONObject();
    jsonObject.putOnce("taskNo", taskNo);
    //类型
    jsonObject.putOnce("taskType", "stationData-ust");
    //第几个
    jsonObject.putOnce("partNo", 1);
    //总共几个
    jsonObject.putOnce("partTotal", 1);
    //数据
    jsonObject.putOnce("data", zipContent);

    String qrCodeContent = jsonObject.toString();

    QrConfig config = this.getQrConfig(500, 500, Color.black, Color.white);

    ServletOutputStream out = response.getOutputStream();

    QrCodeUtil.generate(qrCodeContent, config, IMAGE_TYPE, out);
  }


  /**
   * 二维码生成配置
   *
   * @param width  宽度
   * @param height 高度
   * @param c      二维码颜色
   * @param bc     二维码背景颜色
   * @return
   */
  public QrConfig getQrConfig(int width, int height, Color c, Color bc) {
    QrConfig config = new QrConfig(width, height);
    // 设置边距，既二维码和背景之间的边距
    config.setMargin(1);
    // 设置前景色，既二维码颜色（青色）
    config.setForeColor(c);
    // 设置背景色（灰色）
    config.setBackColor(bc);
    return config;
  }


  /**
   * 获取文件上报数值类型参数
   *
   * @param key
   * @param defaultValue
   * @return
   */
  public int getTranSysParameter(String key, String defaultValue) {
    int returnValue = 0;
    try {
      String value = super.getSysParameter(key, defaultValue);
      returnValue = Integer.parseInt(value);
    } catch (RuntimeException e) {
      String errorInfo = "参数表" + key + "获取失败";
      log.error(errorInfo, e);
      String name = "参数表" + key + "获取失败";
      String describe = "参数表" + key + "获取失败";
      String solution = "使用默认值" + defaultValue;
      super.saveSysAlarm(AlarmTypeEnum.E1, name, describe, errorInfo, solution);
      returnValue = Integer.parseInt(defaultValue);
    }
    return returnValue;
  }
}
