package com.jiayue.ipfcst.dataexchange.service;


import com.jiayue.ipfcst.common.data.entity.InverterStatusData;
import com.jiayue.ipfcst.common.data.entity.WeatherStationStatusData;
import com.jiayue.ipfcst.common.data.entity.WindTowerStatusData;
import com.jiayue.ipfcst.common.data.entity.WindTurbineStatusData;
import com.jiayue.ipfcst.console.service.SysParameterService;
import com.jiayue.ipfcst.dataexchange.dataprocesser.datapacker.AbstractDataPacker;
import com.jiayue.ipfcst.dataexchange.dataprocesser.datapacker.TheoreticalPowerByHubSpeedCalculateFactory;
import com.jiayue.ipfcst.dataexchange.dataprocesser.datapacker.iml.PowerStationDataPacker;
import com.jiayue.ipfcst.dataexchange.dataprocesser.datapacker.iml.PowerStationDataPackerOne;
import com.jiayue.ipfcst.dataexchange.exception.DataExchangeException;
import com.jiayue.ipfcst.dataexchange.service.equipmentstatusdata.*;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j
@Service
@EnableScheduling
public class SaveEquipmentStatusData {

  /**
   * 风塔包装类
   */
  private List<AbstractDataPacker<WindTowerStatusData>> windTowerPackers = Collections.synchronizedList(new ArrayList<>());

  /**
   * 气象站包装类
   */
  private List<AbstractDataPacker<WeatherStationStatusData>> weatherStationPackers = Collections.synchronizedList(new ArrayList<>());

  /**
   * 风机包装类
   */
  private List<AbstractDataPacker<WindTurbineStatusData>> windTurbinePackers = Collections.synchronizedList(new ArrayList<>());

  /**
   * 逆变器包装类
   */
  private List<AbstractDataPacker<InverterStatusData>> inverterPackers = Collections.synchronizedList(new ArrayList<>());


  /**
   * 光伏电站数据包装类
   */
  @Setter
  PowerStationDataPacker powerStationDataPacker;
  /**
   * 风电站数据包装类
   */
  @Setter
  PowerStationDataPackerOne powerStationDataPackerOne;


  @Autowired
  PowerStationStatusDataService powerStationStatusDataService;

  @Autowired
  PowerStationStatusDataOneService powerStationStatusDataOneService;

  @Autowired
  WindTurbineStatusDataService windTurbineStatusDataService;

  @Autowired
  InverterStatusDataService inverterStatusDataService;

  @Autowired
  WeatherStationStatusDataService weatherStationStatusDataService;

  @Autowired
  WindTowerStatusDataService windTowerStatusDataService;

  @Autowired
  SysParameterService sysParameterService;

  public void addWindTowerPacker(AbstractDataPacker<WindTowerStatusData> windTowerPacker) {
    if (windTowerPacker != null) {
      this.windTowerPackers.add(windTowerPacker);
    }
  }

  public void addWeatherStationPacker(AbstractDataPacker<WeatherStationStatusData> weatherStationPacker) {
    if (weatherStationPacker != null) {
      this.weatherStationPackers.add(weatherStationPacker);
    }
  }

  public void addWindTurbinePacker(AbstractDataPacker<WindTurbineStatusData> windTurbinePacker) {
    if (windTurbinePacker != null) {
      this.windTurbinePackers.add(windTurbinePacker);
    }
  }

  public void addInverterPacker(AbstractDataPacker<InverterStatusData> inverterPacker) {
    if (inverterPacker != null) {
      this.inverterPackers.add(inverterPacker);
    }
  }


  public void removeWindTowerPacker(AbstractDataPacker<WindTowerStatusData> windTowerPacker) {
    if (windTowerPacker != null && this.windTowerPackers.contains(windTowerPacker)) {
      this.windTowerPackers.remove(windTowerPacker);
    }
  }

  public void removeWeatherStationPacker(AbstractDataPacker<WeatherStationStatusData> weatherStationPacker) {
    if (weatherStationPacker != null && weatherStationPackers.contains(weatherStationPacker)) {
      this.weatherStationPackers.remove(weatherStationPacker);
    }
  }

  public void removeWindTurbinePacker(AbstractDataPacker<WindTurbineStatusData> windTurbinePacker) {
    if (windTurbinePacker != null && windTurbinePackers.contains(windTurbinePacker)) {
      this.windTurbinePackers.remove(windTurbinePacker);
    }
  }

  public void removeInverterPacker(AbstractDataPacker<InverterStatusData> inverterPacker) {
    if (inverterPacker != null && inverterPackers.contains(inverterPacker)) {
      this.inverterPackers.add(inverterPacker);
    }
  }

  public void addPacker(AbstractDataPacker packer) {
    Class clazz = packer.getT().getClass();
    switch (clazz.getSimpleName()) {
      case "InverterStatusData":
        addInverterPacker((AbstractDataPacker<InverterStatusData>) packer);
        break;
      case "PowerStationStatusData":
        this.powerStationDataPacker = (PowerStationDataPacker) packer;
        break;
      case "PowerStationStatusDataOne":
        this.powerStationDataPackerOne = (PowerStationDataPackerOne) packer;
        break;
      case "WeatherStationStatusData":
        addWeatherStationPacker((AbstractDataPacker<WeatherStationStatusData>) packer);
        break;
      case "WindTowerStatusData":
        addWindTowerPacker((AbstractDataPacker<WindTowerStatusData>) packer);
        break;
      case "WindTurbineStatusData":
        addWindTurbinePacker((AbstractDataPacker<WindTurbineStatusData>) packer);
        break;
      default:
        return;
    }
  }


  public void removePacker(AbstractDataPacker packer) {
    Class clazz = packer.getT().getClass();
    switch (clazz.getSimpleName()) {
      case "InverterStatusData":
        removeInverterPacker((AbstractDataPacker<InverterStatusData>) packer);
        break;
      case "PowerStationStatusData":
        this.powerStationDataPacker = null;
        break;
      case "PowerStationStatusDataOne":
        this.powerStationDataPackerOne = null;
        break;
      case "WeatherStationStatusData":
        removeWeatherStationPacker((AbstractDataPacker<WeatherStationStatusData>) packer);
        break;
      case "WindTowerStatusData":
        removeWindTowerPacker((AbstractDataPacker<WindTowerStatusData>) packer);
        break;
      case "WindTurbineStatusData":
        removeWindTurbinePacker((AbstractDataPacker<WindTurbineStatusData>) packer);
        break;
      default:
        return;
    }
  }


  /**
   * 保存场站数据  1分钟间隔
   */
  @Scheduled(fixedRate = 60000)
  public void saveStationData() {
    int demo = sysParameterService.getTranSysParameter("demo","1");
    if (demo==0){
      if (powerStationDataPacker != null) {
        try {
          powerStationStatusDataService.save(powerStationDataPacker.packageData());
        } catch (DataExchangeException e) {
          log.error("包装光伏场站数据时出错：", e);
        }
      }
      if (powerStationDataPackerOne != null) {
        try {
          powerStationStatusDataOneService.save(powerStationDataPackerOne.packageData());
        } catch (DataExchangeException e) {
          log.error("包装风电场站数据时出错：", e);
        }
      }
    }
  }


  /**
   * 保存气象站数据  1分钟间隔
   */
  @Scheduled(fixedRate = 60000)
  public void saveWeatherStationData() {
    int demo = sysParameterService.getTranSysParameter("demo","1");
    if (demo==0){
      if (weatherStationPackers != null && weatherStationPackers.size() > 0) {
        for (AbstractDataPacker<WeatherStationStatusData> p : weatherStationPackers) {
          try {
            weatherStationStatusDataService.save(p.packageData());
          } catch (DataExchangeException e) {
            log.error("包装气象站数据时出错", e);
          } catch (IllegalAccessException e) {
            log.error("包装气象站数据时出错", e);
          } catch (Exception e) {
            log.error("包装气象站数据,并存储时出错", e);
          }
        }
      }
    }
  }


  /**
   * 保存测风塔数据  1分钟间隔
   */
  @Scheduled(fixedRate = 60000)
  public void saveWindTowerData() {
    int demo = sysParameterService.getTranSysParameter("demo","1");
    if (demo==0){
      if (windTowerPackers != null && windTowerPackers.size() > 0) {
        for (AbstractDataPacker<WindTowerStatusData> p : windTowerPackers) {
          try {
            windTowerStatusDataService.save(p.packageData());
          } catch (DataExchangeException e) {
            log.error("包装测风塔数据时出错", e);
          } catch (IllegalAccessException e) {
            log.error("包装测风塔数据时出错", e);
          } catch (Exception e) {
            log.error("包装测风塔数据,并存储时出错", e);
          }
        }
      }
    }
  }

  /**
   * 获取全厂机头风速法理论功率
   */
  public BigDecimal getTheoreticalPowerByHubSpeedInHoleStation() {
    BigDecimal holePower=BigDecimal.ZERO;
    if (windTurbinePackers != null && windTurbinePackers.size() > 0) {
      WindTurbineStatusData windTurbineStatusData = null;
      for (AbstractDataPacker<WindTurbineStatusData> p : windTurbinePackers) {
        try {
          windTurbineStatusData = p.packageData();
        } catch (Exception e) {
          log.error("包装风机数据时出错", e);
        }
        try {
          windTurbineStatusData = TheoreticalPowerByHubSpeedCalculateFactory.getInstance().calculate(windTurbineStatusData);
          holePower=holePower.add(windTurbineStatusData.getTheoreticalPowerByHubSpeed());
        } catch (Exception e) {
          log.error("计算风机机头风速法理论功率出错", e);
        }
      }
    }
    return holePower;
  }


  /**
   * 保存风机数据  5分钟间隔 每五分钟执行
   */
  @Scheduled(cron = "0 0/5 * * * *")
  public void saveWindTurbineData() {
    int demo = sysParameterService.getTranSysParameter("demo","1");
    if (demo==0){
      if (windTurbinePackers != null && windTurbinePackers.size() > 0) {
        DateTime d = DateTime.now();
        List<WindTurbineStatusData> l = new ArrayList<>();
        WindTurbineStatusData windTurbineStatusData = null;
        for (AbstractDataPacker<WindTurbineStatusData> p : windTurbinePackers) {
          try {
            windTurbineStatusData = p.packageData();
          } catch (Exception e) {
            log.error("包装风机数据时出错", e);
          }
          try {
            windTurbineStatusData = TheoreticalPowerByHubSpeedCalculateFactory.getInstance().calculate(windTurbineStatusData);
          } catch (Exception e) {
            log.error("计算风机机头风速法理论功率出错", e);
          }
          l.add(windTurbineStatusData);
        }
        windTurbineStatusDataService.save(l);
        log.info("存储风机数据总耗时：" + (DateTime.now().getMillis() - d.getMillis()) + "ms");
      }
    }
  }


  /**
   * 保存逆变器数据  5分钟间隔 每五分钟执行
   */
  @Scheduled(cron = "0 0/5 * * * *")
  public void saveInverterData() {
    int demo = sysParameterService.getTranSysParameter("demo","1");
    if (demo==0){
      if (inverterPackers != null && inverterPackers.size() > 0) {
        DateTime d = DateTime.now();
        List<InverterStatusData> l = new ArrayList<>();
        for (AbstractDataPacker<InverterStatusData> p : inverterPackers) {
          try {
            l.add(p.packageData());
          } catch (Exception e) {
            log.error("包装逆变器数据,并存储时出错", e);
          }
        }
        inverterStatusDataService.save(l);
        log.info("存储逆变器数据总耗时：" + (DateTime.now().getMillis() - d.getMillis()) + "ms");
      }
    }
  }
}
