package com.jiayue.ipfcst.console.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.jiayue.ipfcst.common.data.entity.*;
import com.jiayue.ipfcst.common.data.repository.AccuracyPassRateRepository;
import com.jiayue.ipfcst.common.data.repository.ForecastPowerShortTermHisRepository;
import com.jiayue.ipfcst.common.data.repository.ForecastPowerUltraShortTermHisRepository;
import com.jiayue.ipfcst.common.data.repository.PowerStationStatusDataRepository;
import com.jiayue.ipfcst.common.data.service.BaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 西北准确率
 *
 * @author yh
 * @version 2.0
 * @since 2019/7/17 9:30
 */
@Service
@Slf4j
public class AccuracyPassRateCalculateForXBService extends BaseService {

  private final PowerStationStatusDataRepository powerStationStatusDataRepository;
  private final ForecastPowerUltraShortTermHisRepository forecastPowerUltraShortTermHisRepository;
  private final ForecastPowerShortTermHisRepository forecastPowerShortTermHisRepository;
  private final SysParameterService sysParameterService;
  private final AccuracyPassRateRepository accuracyPassRateRepository;

  @Autowired
  public AccuracyPassRateCalculateForXBService(PowerStationStatusDataRepository powerStationStatusDataRepository,
                                               ForecastPowerUltraShortTermHisRepository forecastPowerUltraShortTermHisRepository,
                                               ForecastPowerShortTermHisRepository forecastPowerShortTermHisRepository,
                                               SysParameterService sysParameterService,
                                               AccuracyPassRateRepository accuracyPassRateRepository) {
    this.powerStationStatusDataRepository = powerStationStatusDataRepository;
    this.forecastPowerUltraShortTermHisRepository = forecastPowerUltraShortTermHisRepository;
    this.forecastPowerShortTermHisRepository = forecastPowerShortTermHisRepository;
    this.sysParameterService = sysParameterService;
    this.accuracyPassRateRepository = accuracyPassRateRepository;
  }

  public void generateData(ElectricField electricField) {
    try {
      long startTime = DateUtil.beginOfDay(DateTime.now()).getTime();
      long nowTime = DateTime.now().getTime();
      long moment15 = 900000L;
      BigDecimal nowTimeBig = new BigDecimal(String.valueOf(nowTime));
      BigDecimal moment15Big = new BigDecimal(String.valueOf(moment15));
      BigDecimal queryTimeBig = nowTimeBig.divideAndRemainder(moment15Big)[0].multiply(moment15Big);
      long endTime = queryTimeBig.longValue();

      // 获取短期计算准确率获取该天是提前几天预测的
      String sysParameter = sysParameterService.getSysParameter("ACCURACY_DQ_HOWLONGAGO", "1");
      int howLongAgoForDq = Integer.parseInt(sysParameter);
      // 获取短期数据
      final List<ForecastPowerShortTermHis> shortList = this.forecastPowerShortTermHisRepository.findByForecastTimeBetweenAndForecastHowLongAgo(startTime, endTime, howLongAgoForDq);

      // 获取短期计算准确率获取该天是提前几天预测的
      String sysParameterCdq = sysParameterService.getSysParameter("ACCURACY_CDQ_HOWLONGAGO", "16");
      int howLongAgoForCdq = Integer.parseInt(sysParameterCdq);
      // 获取超短期数据
      List<ForecastPowerUltraShortTermHis> ultraList = this.forecastPowerUltraShortTermHisRepository.findByForecastTimeBetweenAndForecastHowLongAgo(startTime, endTime, howLongAgoForCdq);
      // 获取实际功率
      List<PowerStationStatusData> psList = this.powerStationStatusDataRepository.findByTimeBetween(new Date(startTime), new Date(endTime));
      // 计算实际功率及合格率
      BigDecimal capacity = electricField.getCapacity();
      BigDecimal compare = capacity.multiply(new BigDecimal("0.03"));
      BigDecimal ZERO = new BigDecimal("0");
      AccuracyPassRate accuracyPassRate = new AccuracyPassRate();
      accuracyPassRate.setTime(endTime);
      /************** ***********************************计算短期准确率-start*****************************************************/
      List<PowerStationStatusData> psFilter = psList.stream().filter(p -> p.getTime().getTime() == endTime).collect(Collectors.toList());
      List<ForecastPowerShortTermHis> shortFilter = shortList.stream().filter(u -> u.getForecastTime() == endTime).collect(Collectors.toList());
      if ((psFilter != null && psFilter.size()>0)
        && (shortFilter != null && shortFilter.size()>0)) {
        BigDecimal SJ = psFilter.get(0).getAbleValue();
        BigDecimal DQ = shortFilter.get(0).getAbleValue();
        if ((DQ.floatValue() <= ZERO.floatValue() && SJ.floatValue() <= compare.floatValue())
            ||(DQ.floatValue() <=compare.floatValue() &&SJ.floatValue()<=ZERO.floatValue())) {
          accuracyPassRate.setShortTermAccuracy("不予考核");
        } else {
          BigDecimal b1 = SJ.subtract(DQ);
          BigDecimal b2 =b1.divide(DQ, 8, BigDecimal.ROUND_HALF_UP).abs();
          BigDecimal b3 =new BigDecimal(1).subtract(b2);
          String value = b3.multiply(new BigDecimal(100)).setScale(2,BigDecimal.ROUND_HALF_UP).toString();
          accuracyPassRate.setShortTermAccuracy(value);
        }
      } else {
        accuracyPassRate.setShortTermAccuracy("不予考核");
      }
      /*************************************************计算短期准确率-end*****************************************************/

      /*************************************************计算超短期准确率-start*****************************************************/
      if ((psList != null && psList.size()>0)
        && (ultraList != null&&ultraList.size()>0)) {
        BigDecimal p2 = new BigDecimal("0");
        BigDecimal count = new BigDecimal("0");
        for(Long DateTime = startTime; DateTime <= endTime; DateTime = DateTime +moment15){
          Long finalTime = DateTime;
          List<PowerStationStatusData> psFilterCdq = psList.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
          List<ForecastPowerUltraShortTermHis> ultraFilter = ultraList.stream().filter(u -> u.getForecastTime() == finalTime).collect(Collectors.toList());

          if((psFilterCdq != null && psFilterCdq.size()>0)
            && (ultraFilter  != null&&ultraFilter.size()>0)){
            BigDecimal countCDQ =ultraFilter.get(0).getAbleValue();
            BigDecimal countSJ = psFilterCdq.get(0).getAbleValue();
            if(countCDQ.floatValue()>=compare.floatValue() || countSJ.floatValue()>=compare.floatValue()){
              p2 = p2.add(countSJ.subtract(countCDQ).abs());
            }
          }
        }
        if(p2.floatValue() == 0F){
          accuracyPassRate.setUltraShortTermAccuracy("不予考核");
        }else{
          for(Long DateTime = startTime; DateTime <= endTime; DateTime = DateTime +moment15){
            Long finalTime = DateTime;
            List<PowerStationStatusData> psFilterCdq = psList.stream().filter(p -> p.getTime().getTime() == finalTime).collect(Collectors.toList());
            List<ForecastPowerUltraShortTermHis> ultraFilter = ultraList.stream().filter(u -> u.getForecastTime() == finalTime).collect(Collectors.toList());
            if((psFilterCdq != null && psFilterCdq.size()>0)
              && (ultraFilter  != null&&ultraFilter.size()>0)){
              BigDecimal countCDQ =ultraFilter.get(0).getAbleValue();
              BigDecimal countSJ = psFilterCdq.get(0).getAbleValue();
              if(countCDQ.floatValue()>=compare.floatValue() || countSJ.floatValue()>=compare.floatValue()){
                BigDecimal a =  (countSJ.divide(countSJ.add(countCDQ), 8, BigDecimal.ROUND_HALF_UP).subtract(new BigDecimal(0.5))).abs();
                BigDecimal d = ((countSJ.subtract(countCDQ)).abs()).divide(p2,8, BigDecimal.ROUND_HALF_UP);
                BigDecimal s = a.multiply(d);
                count= count.add(s);
              }
            }
          }
          BigDecimal p1 = (count.multiply(new BigDecimal(2)));
          BigDecimal p3 = (new BigDecimal(1).subtract(p1)).multiply(new BigDecimal(100));
          String value = p3.setScale(2,BigDecimal.ROUND_HALF_UP).toString();
          accuracyPassRate.setUltraShortTermAccuracy(value);
        }
      } else {
        accuracyPassRate.setUltraShortTermAccuracy("不予考核");
      }
      /*************************************************计算超短期准确率-end*****************************************************/
      accuracyPassRateRepository.save(accuracyPassRate);
    } catch (Exception e) {
      e.printStackTrace();
      log.error("西南计算短期和超短期准确率失败" + e);
    }

  }


}
