package com.jiayue.ipfcst.dataexchange.dataprocesser;

import com.jiayue.ipfcst.common.core.exception.BusinessException;
import com.jiayue.ipfcst.common.core.util.SunRiseSet;
import com.jiayue.ipfcst.common.data.entity.ElectricField;
import com.jiayue.ipfcst.common.data.entity.ProtocolGatherDataPoint;
import com.jiayue.ipfcst.console.service.ElectricFieldService;
import com.jiayue.ipfcst.dataexchange.container.ProtocolDataContainer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.LocalTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 针对气象站数据的过滤功能
 *
 * @author: xiuwei
 * @version:
 */
@Component
@Slf4j
public class WeatherStationStatusDataFilter {


  @Autowired
  private ElectricFieldService electricFieldService;

  private ElectricField electricField;
  /**
   * 日升时刻
   */
  private DateTime sunUpTime;
  /**
   * 日落时刻
   */
  private DateTime sunDownTime;

  public boolean radiationValueFiltering(BigDecimal val) {
    if (DateTime.now().isBefore(getSunUpTime().minusMillis(60)) || DateTime.now().isAfter(getSunDownTime().plusMinutes(60))) {
      if (val.compareTo(BigDecimal.ZERO) > 0) {
        return true;
      }
    }
    return false;
  }

  public boolean radiationAccumulationValueFiltering(BigDecimal val) {
    DateTime n=DateTime.now();
    //排除当天0点0分的时间
    if (n.isBefore(getSunUpTime().minusMillis(60))||(n.getHourOfDay()==0) ||(n.getHourOfDay()==23 &&n.getMinuteOfHour()==59) ) {
      if (val.compareTo(BigDecimal.ZERO) > 0) {
        return true;
      }
    }
    return false;
  }


  public void addFilters(List<ProtocolGatherDataPoint> dataPoints) {
    for (ProtocolGatherDataPoint dp : dataPoints) {
      switch (dp.getEquipmentAttribute().getFieldName()) {
        case "globalR":
          ProtocolDataContainer.getInstance().getDataFiltering().addFilter(dp.getId(), (val) -> {
            if (radiationValueFiltering(val)) {
              log.trace("总辐射没有太阳的情况下数值不为零，值为：" + val + ",已置零");
              return BigDecimal.ZERO;
            }
            return val;
          });
          break;
        case "directR":
          ProtocolDataContainer.getInstance().getDataFiltering().addFilter(dp.getId(), (val) -> {
            if (radiationValueFiltering(val)) {
              log.trace("直辐射没有太阳的情况下数值不为零，值为：" + val + ",已置零");
              return BigDecimal.ZERO;
            }
            return val;
          });
          break;
        case "diffuseR":
          ProtocolDataContainer.getInstance().getDataFiltering().addFilter(dp.getId(), (val) -> {
            if (radiationValueFiltering(val)) {
              log.trace("散辐射没有太阳的情况下数值不为零，值为：" + val + ",已置零");
              return BigDecimal.ZERO;
            }
            return val;
          });
          break;
        case "obliqueR":
          ProtocolDataContainer.getInstance().getDataFiltering().addFilter(dp.getId(), (val) -> {
            if (radiationValueFiltering(val)) {
              log.trace("斜辐射没有太阳的情况下数值不为零，值为：" + val + ",已置零");
              return BigDecimal.ZERO;
            }
            return val;
          });
          break;
        case "hourDA":
          ProtocolDataContainer.getInstance().getDataFiltering().addFilter(dp.getId(), (val) -> {
            if (radiationAccumulationValueFiltering(val)) {
              log.trace("日照小时数累计值隔天未清零，值为：" + val + ",已置零");
              return BigDecimal.ZERO;
            }
            return val;
          });
          break;
        case "globalRDA":
          ProtocolDataContainer.getInstance().getDataFiltering().addFilter(dp.getId(), (val) -> {
            if (radiationAccumulationValueFiltering(val)) {
              log.trace("总辐射累计值隔天未清零，值为：" + val + ",已置零");
              return BigDecimal.ZERO;
            }
            return val;
          });
          break;
        case "directRDA":
          ProtocolDataContainer.getInstance().getDataFiltering().addFilter(dp.getId(), (val) -> {
            if (radiationAccumulationValueFiltering(val)) {
              log.trace("直辐射累计值隔天未清零，值为：" + val + ",已置零");
              return BigDecimal.ZERO;
            }
            return val;
          });
          break;
        case "diffuseRDA":
          ProtocolDataContainer.getInstance().getDataFiltering().addFilter(dp.getId(), (val) -> {
            if (radiationAccumulationValueFiltering(val)) {
              log.trace("散辐射累计值隔天未清零，值为：" + val + ",已置零");
              return BigDecimal.ZERO;
            }
            return val;
          });
          break;
        case "obliqueRDA":
          ProtocolDataContainer.getInstance().getDataFiltering().addFilter(dp.getId(), (val) -> {
            if (radiationAccumulationValueFiltering(val)) {
              log.trace("斜辐射累计值隔天未清零，值为：" + val + ",已置零");
              return BigDecimal.ZERO;
            }
            return val;
          });
          break;
      }
    }
  }

  @PostConstruct
  private void init() throws BusinessException {
    electricField = electricFieldService.getElectricField();
    updateTodaySunRiseSetTime();
  }

  /**
   * 刷新今天日出日落时间
   * 由于日升日落 要求精度不是很高 而且预测的数据也比较准确
   */
  public void updateTodaySunRiseSetTime() {
    if (sunUpTime == null || sunUpTime.isBefore(DateTime.now().withMillisOfDay(0))) {
      Date date = DateTime.now().toDate();
      String sunRiseTimeString = SunRiseSet.getSunrise(electricField.getLongitude(), electricField.getLatitude(), date);
      String sunSetTimeString = SunRiseSet.getSunset(electricField.getLongitude(), electricField.getLatitude(), date);
      if (StringUtils.isNotEmpty(sunRiseTimeString)) {
        try {
          sunUpTime = LocalTime.parse(sunRiseTimeString).toDateTimeToday();
        } catch (Exception e) {
          sunUpTime = null;
        }
      }
      if (StringUtils.isNotEmpty(sunSetTimeString)) {
        try {
          this.sunDownTime = LocalTime.parse(sunSetTimeString).toDateTimeToday();
        } catch (Exception e) {
          this.sunDownTime = null;
        }
      }
    }
  }

  public DateTime getSunUpTime() {
    updateTodaySunRiseSetTime();
    return this.sunUpTime;
  }

  public DateTime getSunDownTime() {
    updateTodaySunRiseSetTime();
    return this.sunDownTime;
  }


}
