package com.jiayue.ipfcst.console.service;

import cn.hutool.core.text.csv.CsvUtil;
import cn.hutool.core.text.csv.CsvWriter;
import cn.hutool.core.util.CharsetUtil;
import com.jiayue.ipfcst.common.core.util.DateTimeUtil;
import com.jiayue.ipfcst.common.data.entity.*;
import com.jiayue.ipfcst.common.data.repository.*;
import com.jiayue.ipfcst.fileupload.util.FileUtil;
import com.sun.xml.fastinfoset.algorithm.LongEncodingAlgorithm;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 业务数据定时导出业务层
 */
@AllArgsConstructor
@Service
@Slf4j
@Transactional
public class BusinessDataBackupService {


  PowerStationStatusDataRepository powerStationStatusDataRepository;

  WeatherStationStatusDataRepository weatherStationStatusDataRepository;

  WindTowerStatusDataRepository windTowerStatusDataRepository;

  WindTurbineStatusDataRepository windTurbineStatusDataRepository;

  InverterStatusDataRepository inverterStatusDataRepository;

  ElectricFieldService electricFieldService;

  @SneakyThrows
  public void dataBackup() {
    log.info("-----------------开始执行业务数据备份任务----------------------");
    long currentDate = DateTimeUtil.getMillisecondsSubDay();//今日凌晨
    long startTime = currentDate - 60 * 60 * 24 * 1000L;
    //Long startTime = 1637683200000L;
    long endTime = currentDate - 1000;
    //Long endTime = 1637769300000L;
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");

    ElectricField electricField = electricFieldService.getElectricField();
    List<WeatherStationStatusData> weatherStationStatusDataList;
    List<InverterStatusData> inverterStatusDataList;
    List<WindTowerStatusData> windTowerStatusDataList;
    List<WindTurbineStatusData> windTurbineStatusDataList;
    List<PowerStationStatusData> powerStationStatusDataList;
    if (electricField.getElectricFieldTypeEnum().getCode() == 1) {
      //光伏
      //-----------------------------------------气象站--------------------------------------
      weatherStationStatusDataList = weatherStationStatusDataRepository.findByTimeBetween(new Date(startTime), new Date(endTime));
      List<WeatherStationStatusData> weatherStationStatusDataCollect = weatherStationStatusDataList.stream().filter(w -> w.getIsGenerated().equals(false)).collect(Collectors.toList());
      //排序
      weatherStationStatusDataCollect.sort(Comparator.comparing(WeatherStationStatusData::getTime));
      //创建气象站文件
      this.createWeatherStationFile(startTime, endTime, electricField, simpleDateFormat, weatherStationStatusDataCollect);
      //---------------------------------------------逆变器---------------------------------------------
      inverterStatusDataList = inverterStatusDataRepository.findByTimeBetween(new Date(startTime), new Date(endTime));
      //排序
      inverterStatusDataList.sort(Comparator.comparing(InverterStatusData::getTime));
      //创建逆变器文件
      this.createInverterStatusDataFile(startTime, endTime, electricField, simpleDateFormat, inverterStatusDataList);
    } else {
      //风电
      //测风塔
      windTowerStatusDataList = windTowerStatusDataRepository.findByTimeBetween(new Date(startTime), new Date(endTime));
      List<WindTowerStatusData> windTowerStatusDataCollect = windTowerStatusDataList.stream().filter(w -> w.getIsGenerated().equals(false)).collect(Collectors.toList());
      //排序
      windTowerStatusDataCollect.sort(Comparator.comparing(WindTowerStatusData::getTime));
      //创建测风塔文件
      this.createWindTowerStatusFile(startTime, endTime, electricField, simpleDateFormat, windTowerStatusDataCollect);
      //风机
      windTurbineStatusDataList = windTurbineStatusDataRepository.findByTimeBetween(new Date(startTime), new Date(endTime));
      //排序
      windTurbineStatusDataList.sort(Comparator.comparing(WindTurbineStatusData::getTime));
      //创建风机文件
      this.createWindTurbineStatusFile(startTime, endTime, electricField, simpleDateFormat, windTurbineStatusDataList);
    }
    //实际功率
    powerStationStatusDataList = powerStationStatusDataRepository.findByTimeBetween(new Date(startTime), new Date(endTime));
    //排序
    powerStationStatusDataList.sort(Comparator.comparing(PowerStationStatusData::getTime));
    //创建实际功率文件
    this.createPowerStationStatusFile(startTime, endTime, electricField, simpleDateFormat, powerStationStatusDataList);

  }

  /**
   * 创建气象站文件
   *
   * @param startTime                       开始时间
   * @param endTime                         结束时间
   * @param electricField                   场站
   * @param simpleDateFormat                时间格式化
   * @param weatherStationStatusDataCollect 数据
   */
  public void createWeatherStationFile(Long startTime, Long endTime, ElectricField electricField, SimpleDateFormat simpleDateFormat, List<WeatherStationStatusData> weatherStationStatusDataCollect) {
    List<WeatherStationStatusData> wFilter = new ArrayList<>();
    for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + 1000 * 60 * 5L) {
      long finalTime = stepTime;
      List<WeatherStationStatusData> ws = weatherStationStatusDataCollect.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
      if (ws != null && ws.size() > 0) {
        wFilter.add(ws.get(0));
      }
    }
    //文件名
    String fileName = electricField.getStationCode() + "-" + simpleDateFormat.format(startTime) + "-" + "weatherStation" + ".csv";
    //第一行
    String[] listName = new String[18];
    listName[0] = "time";
    listName[1] = "status";
    listName[2] = "equipmentNo";
    listName[3] = "globalR";
    listName[4] = "directR";
    listName[5] = "diffuseR";
    listName[6] = "obliqueR";
    listName[7] = "airT";
    listName[8] = "p";
    listName[9] = "rh";
    listName[10] = "cellT";
    listName[11] = "ws";
    listName[12] = "wd";
    listName[13] = "hourDA";
    listName[14] = "globalRDA";
    listName[15] = "directRDA";
    listName[16] = "diffuseRDA";
    listName[17] = "obliqueRDA";
    //获取String[]类型的数据至result中
    List<String[]> result = new ArrayList<>();
    //将listName添加到result中
    result.add(listName);
    for (WeatherStationStatusData w : wFilter) {
      //获取weatherStationStatusDataList对象的数据作为listValue
      String[] listValue = new String[18];
      listValue[0] = String.valueOf(w.getTime());
      listValue[1] = String.valueOf(w.getStatus());
      listValue[2] = String.valueOf(w.getEquipmentNo());
      listValue[3] = String.valueOf(w.getGlobalR());
      listValue[4] = String.valueOf(w.getDirectR());
      listValue[5] = String.valueOf(w.getDiffuseR());
      listValue[6] = String.valueOf(w.getObliqueR());
      listValue[7] = String.valueOf(w.getAirT());
      listValue[8] = String.valueOf(w.getP());
      listValue[9] = String.valueOf(w.getRh());
      listValue[10] = String.valueOf(w.getCellT());
      listValue[11] = String.valueOf(w.getWs());
      listValue[12] = String.valueOf(w.getWd());
      listValue[13] = String.valueOf(w.getHourDA());
      listValue[14] = String.valueOf(w.getGlobalRDA());
      listValue[15] = String.valueOf(w.getDirectRDA());
      listValue[16] = String.valueOf(w.getDiffuseRDA());
      listValue[17] = String.valueOf(w.getObliqueRDA());
      result.add(listValue);
    }
    this.createCsvFile(result, fileName);
  }

  /**
   * 创建逆变器文件
   *
   * @param startTime              开始时间
   * @param endTime                结束时间
   * @param electricField          场站
   * @param simpleDateFormat       时间格式化
   * @param inverterStatusDataList 数据
   */
  public void createInverterStatusDataFile(Long startTime, Long endTime, ElectricField electricField, SimpleDateFormat simpleDateFormat, List<InverterStatusData> inverterStatusDataList) {
    List<InverterStatusData> iFilter = new ArrayList<>();
    for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + 1000 * 60 * 5L) {
      long finalTime = stepTime;
      List<InverterStatusData> is = inverterStatusDataList.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
      if (is != null && is.size() > 0) {
        iFilter.add(is.get(0));
      }
    }
    //文件名
    String iFileName = electricField.getStationCode() + "-" + simpleDateFormat.format(startTime) + "-" + "inverterStatus" + ".csv";
    //第一行
    String[] iListName = new String[5];
    iListName[0] = "time";
    iListName[1] = "status";
    iListName[2] = "equipmentNo";
    iListName[3] = "activePower";
    iListName[4] = "reactivePower";
    //获取String[]类型的数据至result中
    List<String[]> result = new ArrayList<>();
    //将listName添加到result中
    result.add(iListName);
    for (InverterStatusData i : iFilter) {
      //获取weatherStationStatusDataList对象的数据作为listValue
      String[] listValue = new String[5];
      listValue[0] = String.valueOf(i.getTime());
      listValue[1] = String.valueOf(i.getStatus());
      listValue[2] = String.valueOf(i.getEquipmentNo());
      listValue[3] = String.valueOf(i.getActivePower());
      listValue[4] = String.valueOf(i.getReactivePower());
      result.add(listValue);
    }
    this.createCsvFile(result, iFileName);
  }

  /**
   * 创建测风塔文件
   *
   * @param startTime                  开始时间
   * @param endTime                    结束时间
   * @param electricField              场站
   * @param simpleDateFormat           时间格式化
   * @param windTowerStatusDataCollect 数据
   */
  public void createWindTowerStatusFile(Long startTime, Long endTime, ElectricField electricField, SimpleDateFormat simpleDateFormat, List<WindTowerStatusData> windTowerStatusDataCollect) {
    List<WindTowerStatusData> wFilter = new ArrayList<>();
    for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + 1000 * 60 * 5L) {
      long finalTime = stepTime;
      List<WindTowerStatusData> wind = windTowerStatusDataCollect.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
      if (wind != null && wind.size() > 0) {
        wFilter.add(wind.get(0));
      }
    }
    //文件名
    String fileName = electricField.getStationCode() + "-" + simpleDateFormat.format(startTime) + "-" + "windTowerStatus" + ".csv";
    //第一行
    String[] listName = new String[29];
    listName[0] = "time";
    listName[1] = "status";
    listName[2] = "equipmentNo";
    listName[3] = "tInst";
    listName[4] = "rhInst";
    listName[5] = "paInst";
    listName[6] = "wsInst10";
    listName[7] = "wdInst10";
    listName[8] = "wsInst30";
    listName[9] = "wdInst30";
    listName[10] = "wsInst50";
    listName[11] = "wdInst50";
    listName[12] = "wsInst60";
    listName[13] = "wdInst60";
    listName[14] = "wsInst70";
    listName[15] = "wdInst70";
    listName[16] = "wsInst80";
    listName[17] = "wdInst80";
    listName[18] = "wsInst90";
    listName[19] = "wdInst90";
    listName[20] = "wsInst100";
    listName[21] = "wdInst100";
    listName[22] = "wsInst110";
    listName[23] = "wdInst110";
    listName[24] = "wsInst120";
    listName[25] = "wdInst120";
    listName[26] = "wsInstHubHeight";
    listName[27] = "wdInstHubHeight";
    listName[28] = "airDensity";
    //获取String[]类型的数据至result中
    List<String[]> result = new ArrayList<>();
    //将listName添加到result中
    result.add(listName);
    for (WindTowerStatusData w : wFilter) {
      //获取weatherStationStatusDataList对象的数据作为listValue
      String[] listValue = new String[29];
      listValue[0] = String.valueOf(w.getTime());
      listValue[1] = String.valueOf(w.getStatus());
      listValue[2] = String.valueOf(w.getEquipmentNo());
      listValue[3] = String.valueOf(w.getTInst());
      listValue[4] = String.valueOf(w.getRhInst());
      listValue[5] = String.valueOf(w.getPaInst());
      listValue[6] = String.valueOf(w.getWsInst10());
      listValue[7] = String.valueOf(w.getWdInst10());
      listValue[8] = String.valueOf(w.getWsInst30());
      listValue[9] = String.valueOf(w.getWdInst30());
      listValue[10] = String.valueOf(w.getWsInst50());
      listValue[11] = String.valueOf(w.getWdInst50());
      listValue[12] = String.valueOf(w.getWdInst60());
      listValue[13] = String.valueOf(w.getWdInst60());
      listValue[14] = String.valueOf(w.getWsInst70());
      listValue[15] = String.valueOf(w.getWdInst70());
      listValue[16] = String.valueOf(w.getWsInst80());
      listValue[17] = String.valueOf(w.getWdInst80());
      listValue[18] = String.valueOf(w.getWsInst90());
      listValue[19] = String.valueOf(w.getWdInst90());
      listValue[20] = String.valueOf(w.getWsInst100());
      listValue[21] = String.valueOf(w.getWdInst100());
      listValue[22] = String.valueOf(w.getWsInst110());
      listValue[23] = String.valueOf(w.getWdInst100());
      listValue[24] = String.valueOf(w.getWsInst120());
      listValue[25] = String.valueOf(w.getWdInst120());
      listValue[26] = String.valueOf(w.getWsInstHubHeight());
      listValue[27] = String.valueOf(w.getWdInstHubHeight());
      listValue[28] = String.valueOf(w.getAirDensity());
      result.add(listValue);
    }
    this.createCsvFile(result, fileName);
  }

  /**
   * 创建风机文件
   *
   * @param startTime                 开始时间
   * @param endTime                   结束时间
   * @param electricField             场站
   * @param simpleDateFormat          时间格式化
   * @param windTurbineStatusDataList 数据
   */
  public void createWindTurbineStatusFile(Long startTime, Long endTime, ElectricField electricField, SimpleDateFormat simpleDateFormat, List<WindTurbineStatusData> windTurbineStatusDataList) {
    List<WindTurbineStatusData> wtFilter = new ArrayList<>();
    for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + 1000 * 60 * 5L) {
      long finalTime = stepTime;
      List<WindTurbineStatusData> is = windTurbineStatusDataList.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
      if (is != null && is.size() > 0) {
        wtFilter.add(is.get(0));
      }
    }
    //文件名
    String fileName = electricField.getStationCode() + "-" + simpleDateFormat.format(startTime) + "-" + "windTurbineStatus" + ".csv";
    //第一行
    String[] listName = new String[9];
    listName[0] = "time";
    listName[1] = "status";
    listName[2] = "equipmentNo";
    listName[3] = "activePower";
    listName[4] = "reactivePower";
    listName[5] = "ws";
    listName[6] = "wd";
    listName[7] = "t";
    listName[8] = "cumulativeGeneratedEnergy";
    //获取String[]类型的数据至result中
    List<String[]> result = new ArrayList<>();
    //将listName添加到result中
    result.add(listName);
    for (WindTurbineStatusData i : wtFilter) {
      //获取weatherStationStatusDataList对象的数据作为listValue
      String[] listValue = new String[9];
      listValue[0] = String.valueOf(i.getTime());
      listValue[1] = String.valueOf(i.getStatus());
      listValue[2] = String.valueOf(i.getEquipmentNo());
      listValue[3] = String.valueOf(i.getActivePower());
      listValue[4] = String.valueOf(i.getReactivePower());
      listValue[5] = String.valueOf(i.getWs());
      listValue[6] = String.valueOf(i.getWd());
      listValue[7] = String.valueOf(i.getT());
      listValue[8] = String.valueOf(i.getCumulativeGeneratedEnergy());
      result.add(listValue);
    }
    this.createCsvFile(result, fileName);
  }

  /**
   * 创建实际功率文件
   *
   * @param startTime                  开始时间
   * @param endTime                    结束时间
   * @param electricField              场站
   * @param simpleDateFormat           时间格式化
   * @param powerStationStatusDataList 数据
   */
  public void createPowerStationStatusFile(Long startTime, Long endTime, ElectricField electricField, SimpleDateFormat simpleDateFormat, List<PowerStationStatusData> powerStationStatusDataList) {
    List<PowerStationStatusData> pFilter = new ArrayList<>();
    for (long stepTime = startTime; stepTime <= endTime; stepTime = stepTime + 1000 * 60 * 5L) {
      long finalTime = stepTime;
      List<PowerStationStatusData> is = powerStationStatusDataList.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
      if (is != null && is.size() > 0) {
        pFilter.add(is.get(0));
      }
    }
    //文件名
    String fileName = electricField.getStationCode() + "-" + simpleDateFormat.format(startTime) + "-" + "powerStationStatus" + ".csv";
    //第一行
    String[] listName = new String[3];
    listName[0] = "time";
    listName[1] = "status";
    listName[2] = "realValue";
    //获取String[]类型的数据至result中
    List<String[]> result = new ArrayList<>();
    //将listName添加到result中
    result.add(listName);
    for (PowerStationStatusData p : pFilter) {
      //获取weatherStationStatusDataList对象的数据作为listValue
      String[] listValue = new String[3];
      listValue[0] = String.valueOf(p.getTime());
      listValue[1] = String.valueOf(p.getStatus());
      listValue[2] = String.valueOf(p.getRealValue());
      result.add(listValue);
    }
    this.createCsvFile(result, fileName);
  }

  /**
   * 导出csv格式工具类
   *
   * @param result   导出数据
   * @param fileName 文件名
   */
  public void createCsvFile(List<String[]> result, String fileName) {
    try {

      long currentDate = DateTimeUtil.getMillisecondsSubDay();//今日凌晨
      long startTime = currentDate - 60 * 60 * 24 * 1000L;
      File csvFile = new File(fileName);  //构造文件
      //导入HuTool中CSV工具包的CsvWriter类
      //设置导出字符类型, CHARSET_UTF_8
      ElectricField electricField = electricFieldService.getElectricField();
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMM");

      String path = FileUtil.getSystemFilePath() + File.separator + "dataBackup" + File.separator + electricField.getStationCode() + "-" + simpleDateFormat.format(startTime);

      CsvWriter writer = CsvUtil.getWriter(path + File.separator + csvFile.getName(), CharsetUtil.CHARSET_UTF_8);

      writer.write(result);  //通过CsvWriter中的write方法写入数据
      writer.close();   //关闭CsvWriter
//      //保存文件
//      FileInputStream fileInputStream = new FileInputStream(csvFile);
//      this.saveFile(fileInputStream,csvFile.getName());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * 文件保存
   *
   * @param inputStream 流
   * @param fileName    文件名
   */
  private void saveFile(InputStream inputStream, String fileName) {
    OutputStream os = null;
    try {
      long currentDate = DateTimeUtil.getMillisecondsSubDay();//今日凌晨
      long startTime = currentDate - 60 * 60 * 24 * 1000L;
      //保存文件路径
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMM");
      ElectricField electricField = electricFieldService.getElectricField();
      String path = FileUtil.getSystemFilePath() + File.separator + "dataBackup" + File.separator + electricField.getStationCode() + "-" + simpleDateFormat.format(startTime);
      //String path = "D:\\cscFile\\";
      // 1K的数据缓冲
      byte[] bs = new byte[1024];
      // 读取到的数据长度
      int len;
      // 输出的文件流保存到本地文件
      File tempFile = new File(path);
      if (!tempFile.exists()) {
        tempFile.mkdirs();
      }
      os = new FileOutputStream(tempFile.getPath() + File.separator + fileName);
      // 开始读取
      while ((len = inputStream.read(bs)) != -1) {
        os.write(bs, 0, len);
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      // 完毕，关闭所有链接
      try {
        os.close();
        inputStream.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }


}
