package com.jiayue.ipfcst.service;

import com.jiayue.ipfcst.common.core.exception.BusinessException;
import com.jiayue.ipfcst.common.data.entity.ElectricField;
import com.jiayue.ipfcst.common.data.entity.ForecastPowerShortTermHis;
import com.jiayue.ipfcst.common.data.entity.ForecastPowerUltraShortTermHis;
import com.jiayue.ipfcst.common.data.entity.PowerStationStatusData;
import com.jiayue.ipfcst.common.data.repository.ForecastPowerUltraShortTermHisRepository;
import com.jiayue.ipfcst.common.data.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 历史预测超短期业务层
 *
 * @author yh
 * @version 1.0
 * @since 2019/8/5 16:02
 */
@Service
public class ForecastPowerUltraShortTermHisService extends BaseService {
  private final ForecastPowerUltraShortTermHisRepository forecastPowerUltraShortTermHisRepository;

  private final PowerStationStatusDataService powerStationStatusDataService;
  private final ElectricFieldService electricFieldService;

  @Autowired
  public ForecastPowerUltraShortTermHisService(ForecastPowerUltraShortTermHisRepository forecastPowerUltraShortTermHisRepository,PowerStationStatusDataService powerStationStatusDataService,ElectricFieldService electricFieldService){
    this.forecastPowerUltraShortTermHisRepository = forecastPowerUltraShortTermHisRepository;
    this.powerStationStatusDataService = powerStationStatusDataService;
    this.electricFieldService = electricFieldService;
  }

  /**
   * 根据提前多久，开始结束时间查询历史超短期 yh
   * @param startTime 开始时间
   * @param endTime 结束时间
   * @param ago 提前多久预测
   * @return 结果集
   */
  @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
  public Map<String,Object> findByForecastTimeBetweenAndForecastHowLongAgoOrderByForecastTime(Long startTime,Long endTime,Integer ago){
    Map<String,Object> map = new HashMap<>();
    List<ForecastPowerUltraShortTermHis> list = forecastPowerUltraShortTermHisRepository.findByForecastTimeBetweenAndForecastHowLongAgo(startTime,endTime,ago);
    list.sort(Comparator.comparing(ForecastPowerUltraShortTermHis::getForecastTime));
    long timeStep = 900000L;
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    List<String> times = new ArrayList<>();
    List<Float> datas =new ArrayList<>();
    if(startTime%timeStep !=0){
      startTime = startTime -(startTime%timeStep)+timeStep;
    }
    if(list !=null && list.size()>0){
      for(Long i= startTime;i<endTime;i=i+timeStep){
        long finalI = i;
        List<ForecastPowerUltraShortTermHis> filterList  = list.stream().filter(t->t.getForecastTime() ==finalI).collect(Collectors.toList());
        if(filterList!=null&&filterList.size()>0){
          datas.add(filterList.get(0).getAbleValue().floatValue());
        }else{
          datas.add(null);
        }

        times.add(sdf.format(new Date(finalI)) );
      }
    }
    map.put("times",times);
    map.put("datas",datas);

    return map;

  }

  /**
   * 根据提前多久，开始结束时间查询历史超短期 yh
   * @param startTime 开始时间
   * @param endTime 结束时间
   * @param ago 提前多久预测
   * @return 结果集
   */
  @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
  public Map<String,Object> findByForecastTimeBetweenAndForecastHowLongAgoOrderByForecastTimeForDB(Long startTime,Long endTime,Integer ago,Long timeStep){
    Map<String,Object> map = new HashMap<>();
    List<ForecastPowerUltraShortTermHis> list = forecastPowerUltraShortTermHisRepository.findByForecastTimeBetweenAndForecastHowLongAgo(startTime,endTime,ago);
    list.sort(Comparator.comparing(ForecastPowerUltraShortTermHis::getForecastTime));
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    List<String> times = new ArrayList<>();
    List<Float> datas =new ArrayList<>();
    if(startTime%timeStep !=0){
      startTime = startTime -(startTime%timeStep)+timeStep;
    }
    for(Long i= startTime;i<endTime;i=i+timeStep){
      if(list !=null && list.size()>0){
        long finalI = i;
        List<ForecastPowerUltraShortTermHis> filterList  = list.stream().filter(t->t.getForecastTime() ==finalI).collect(Collectors.toList());
        if(filterList!=null&&filterList.size()>0){
          datas.add(filterList.get(0).getAbleValue().floatValue());
        }else{
          datas.add(null);
        }

      }else {
        datas.add(null);
      }
      times.add(sdf.format(new Date(i)) );


    }

    map.put("times",times);
    map.put("datas",datas);

    return map;

  }

  /**
   * 超短期查询16个点数据 tl
   * @param startTime 开始时间
   * @return 结果集
   */
  @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
  public Map<String,Object> findByForecastRealTimeUltraShortTerm16(Long startTime)throws BusinessException {
    Long endTime = startTime + 60*60*1000*24;
//    List<Map<String,Object>> valueList16 = new ArrayList<>();
    //取出16点数据存入集合中
    Map<String,Object> realPowerMap = new HashMap<>();
    List<ForecastPowerUltraShortTermHis> forecastPowerUltraShortTermHisList = forecastPowerUltraShortTermHisRepository.findByForecastTimeBetween(startTime, endTime);
    for(int p = 1;p<=16;p++){

      int finalP = p;
      List<ForecastPowerUltraShortTermHis> filterList  = forecastPowerUltraShortTermHisList.stream().filter(t->t.getForecastHowLongAgo() == finalP).collect(Collectors.toList());

//      List<ForecastPowerUltraShortTermHis> forecastPowerUltraShortTermHisList = forecastPowerUltraShortTermHisRepository.findByForecastTimeBetweenAndForecastHowLongAgo(startTime, endTime, p);

      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      long timeStep = 900000L;
      if (startTime % timeStep != 0) {
        startTime = startTime - (startTime % timeStep);
      }
      List<Float> ableDatas = new ArrayList<>();
      List<String> times = new ArrayList<>();

      for (long i = startTime; i < endTime; i = i + 900000L) {
        long finalI = i;
        List<ForecastPowerUltraShortTermHis> p1 = filterList.stream().filter(t -> t.getForecastTime() == finalI).collect(Collectors.toList());
        if (p1 != null && p1.size() > 0) {

          if (p1.get(0).getAbleValue().compareTo(new BigDecimal(-99)) == 0) {
            ableDatas.add(0f);
          } else {
            ableDatas.add(p1.get(0).getAbleValue().floatValue());
          }
        } else {
          ableDatas.add(null);
        }
      }
      realPowerMap.put("value"+p,ableDatas);
    }

    Map<String, Object> map = powerStationStatusDataService.findByTimeBetweenForContrast(new Date(startTime), new Date(endTime),900000l);

    ElectricField electricField = electricFieldService.get();
    map.put("value",realPowerMap);
    map.put("capacity",electricField.getCapacity());
    return map;

  }


}
