package com.jiayue.ipfcst.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.jiayue.ipfcst.common.data.entity.PrValue;
import com.jiayue.ipfcst.common.data.repository.ElectricFieldRepository;
import com.jiayue.ipfcst.common.data.repository.PowerStationStatusDataRepository;
import com.jiayue.ipfcst.common.data.repository.PrValueRepository;
import com.jiayue.ipfcst.common.data.repository.WeatherStationStatusDataRepository;
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.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

/**
 * pr值业务层
 *
 * @author fxy
 * @version 1.0
 * @since 2022/10/26 11:23
 */
@Service
@Slf4j
public class PrValueService extends BaseService {

  private final PrValueRepository prValueRepository;
  private final WeatherStationStatusDataRepository weatherStationStatusDataRepository;
  private final PowerStationStatusDataRepository powerStationStatusDataRepository;
  private final ElectricFieldRepository electricFieldRepository;

  @Autowired
  public PrValueService(PrValueRepository prValueRepository, WeatherStationStatusDataRepository weatherStationStatusDataRepository, PowerStationStatusDataRepository powerStationStatusDataRepository, ElectricFieldRepository electricFieldRepository
  ) {
    this.prValueRepository = prValueRepository;
    this.weatherStationStatusDataRepository = weatherStationStatusDataRepository;
    this.powerStationStatusDataRepository = powerStationStatusDataRepository;
    this.electricFieldRepository = electricFieldRepository;
  }

  public Map<String, Object> getData(Long startTime, Long endTime) {


    Map<String, Object> map = new HashMap<>();
    //根据开始时间结束时间获取prValue表里的数据
    List<PrValue> prValueList = prValueRepository.findByTimeBetween(new Date(startTime), new Date(endTime));

    List<Map<String, Object>> dayList = new ArrayList<>();
    List<Map<String, Object>> monthList = new ArrayList<>();
    List<Map<String, Object>> prValueLists = new ArrayList<>();

    String displayPrValue = "0";
    try {
      displayPrValue = super.getSysParameter("DISPLAY_PR_VALUE", "0");
    } catch (RuntimeException e) {
      String errorInfo = "参数表DISPLAY_PR_VALUE获取失败";
      log.error(errorInfo, e);
    }
    if (displayPrValue.equals("1")) {
      //遍历集合
      if (prValueList != null) {
        for (int i = 0; i < prValueList.size(); i++) {
          Map<String, Object> prMap = new HashMap<>();
          //判断理论发电量是否小于等于0
          if (prValueList.get(i).getTheoreticalPowerGeneration().compareTo(BigDecimal.ZERO) == -1 || prValueList.get(i).getTheoreticalPowerGeneration().compareTo(BigDecimal.ZERO) == 0) {
            prMap.put("theoreticalPowerGeneration", "--");
          } else {
            prMap.put("theoreticalPowerGeneration", prValueList.get(i).getTheoreticalPowerGeneration());
          }
          //判断装机容量小于等于0
          if (prValueList.get(i).getCapacity().compareTo(BigDecimal.ZERO) == -1) {
            prMap.put("capacity", "--");
          } else {
            prMap.put("capacity", prValueList.get(i).getCapacity());
          }
          //判断日照小时数是否小于等于0
          if (prValueList.get(i).getHourDA().compareTo(BigDecimal.ZERO) == -1 || prValueList.get(i).getHourDA().compareTo(BigDecimal.ZERO) == 0) {
            prMap.put("hourDA", "--");
          } else {
            prMap.put("hourDA", prValueList.get(i).getHourDA());
          }
          prMap.put("ultraShortTermAccuracy", prValueList.get(i).getUltraShortTermAccuracy());
          //判断pr值是否小于等于0
          if (prValueList.get(i).getPrValue().compareTo(BigDecimal.ZERO) == -1 || prValueList.get(i).getPrValue().compareTo(BigDecimal.ZERO) == 0) {
            prMap.put("prValue", "--");
          } else {
            prMap.put("prValue", prValueList.get(i).getPrValue().multiply(new BigDecimal(100)).setScale(2));
          }
          //判断实际发电量是否小于等于0
          if (prValueList.get(i).getActualPowerGeneration().compareTo(BigDecimal.ZERO) == -1 || prValueList.get(i).getActualPowerGeneration().compareTo(BigDecimal.ZERO) == 0) {
            prMap.put("actualPowerGeneration", "--");
          } else {
            prMap.put("actualPowerGeneration", prValueList.get(i).getActualPowerGeneration());
          }
          prMap.put("time", String.valueOf(prValueList.get(i).getTime()).substring(0, 10));
          dayList.add(prMap);
          prValueLists.add(prMap);
        }

        //获取开始时间所在月份的第一天
        LocalDate localDateFirst = LocalDateTime.ofInstant(Instant.ofEpochMilli(startTime), ZoneId.systemDefault()).toLocalDate();
        LocalDate monthFirst = localDateFirst.with(TemporalAdjusters.firstDayOfMonth());
        Date dateFirst = Date.from(monthFirst.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
        //获取结束时间所在月份最后一天
        LocalDate localDateEnd = LocalDateTime.ofInstant(Instant.ofEpochMilli(endTime), ZoneId.systemDefault()).toLocalDate();
        LocalDate monthEnd = localDateEnd.with(TemporalAdjusters.lastDayOfMonth());
        Date dateEnd = Date.from(monthEnd.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
        //月统计
        //根据开始时间、结束时间按月份分组
        List<DateTime> dateTimes = DateUtil.rangeToList(dateFirst, dateEnd, DateField.MONTH);
        //判断dateTimes是否为空
        if (dateTimes != null) {
          for (int i = 0; i < dateTimes.size(); i++) {
            Map<String, Object> monthMap = new HashMap<>();
            SimpleDateFormat date = new SimpleDateFormat("yyyy-MM");
            String dateTime = date.format(dateTimes.get(i));
            //按照月份进行过滤
            List<PrValue> prValueListFilter = prValueList.stream().filter(prValue -> date.format(prValue.getTime()).equals(dateTime)).collect(Collectors.toList());
            //判断集合
            if (prValueList.size() == 0) {
              continue;
            }
            //过滤掉日照小时数小于0的
            List<PrValue> hourDAList = prValueListFilter.stream().filter(prValue -> prValue.getHourDA().compareTo(BigDecimal.ZERO) == 1).collect(Collectors.toList());
            //日照小时数求和
            BigDecimal hourDAResult = hourDAList.stream().map(PrValue::getHourDA).reduce(BigDecimal.ZERO, BigDecimal::add);
            //过滤掉理论发电量小于0的
            List<PrValue> theoreticalPowerGenerationList = prValueListFilter.stream().filter(prValue -> prValue.getHourDA().compareTo(BigDecimal.ZERO) == 1).collect(Collectors.toList());
            //理论发电量求和
            BigDecimal theoreticalPowerGenerationResult = theoreticalPowerGenerationList.stream().map(PrValue::getTheoreticalPowerGeneration).reduce(BigDecimal.ZERO, BigDecimal::add);
            //实际发电量求和
            BigDecimal actualPowerGenerationResult = prValueListFilter.stream().map(PrValue::getActualPowerGeneration).reduce(BigDecimal.ZERO, BigDecimal::add);
            //pr值求和
            BigDecimal prValueResult = BigDecimal.ZERO;
            //如果理论发电量大于0，pr值 = 实际发电量/理论发电量
            if (theoreticalPowerGenerationResult.compareTo(BigDecimal.ZERO) == 1) {
              prValueResult = actualPowerGenerationResult.multiply(new BigDecimal(100)).divide(theoreticalPowerGenerationResult, 2, BigDecimal.ROUND_HALF_UP);
            }
            //如果日照小时数小于等于0，将日照小时数赋值为 --
            if (hourDAResult.compareTo(BigDecimal.ZERO) == -1 || hourDAResult.compareTo(BigDecimal.ZERO) == 0) {
              monthMap.put("hourDA", "--");
            } else {
              monthMap.put("hourDA", hourDAResult);
            }
            //如果理论发电量小于等于0，将理论发电量数赋值为 --
            if (theoreticalPowerGenerationResult.compareTo(BigDecimal.ZERO) == -1 || theoreticalPowerGenerationResult.compareTo(BigDecimal.ZERO) == 0) {
              monthMap.put("theoreticalPowerGeneration", "--");
            } else {
              monthMap.put("theoreticalPowerGeneration", theoreticalPowerGenerationResult);
            }
            //如果实际发电量小于等于0，将实际发电量数赋值为 --
            if (actualPowerGenerationResult.compareTo(BigDecimal.ZERO) == -1 || actualPowerGenerationResult.compareTo(BigDecimal.ZERO) == 0) {
              monthMap.put("actualPowerGeneration", "--");
            } else {
              monthMap.put("actualPowerGeneration", actualPowerGenerationResult);
            }
            if (prValueResult.compareTo(BigDecimal.ZERO) == -1 || prValueResult.compareTo(BigDecimal.ZERO) == 0) {
              monthMap.put("prValue", "--");
            } else {
              monthMap.put("prValue", prValueResult.setScale(2));
            }

            if (prValueListFilter != null && prValueListFilter.size() > 0 && prValueListFilter.get(0).getCapacity().compareTo(BigDecimal.ZERO) == 1) {
              monthMap.put("capacity", prValueListFilter.get(0).getCapacity());
            } else {
              monthMap.put("capacity", "--");
            }
            monthMap.put("time", dateTime);
            monthMap.put("ultraShortTermAccuracy", 0.98);
            monthList.add(monthMap);
          }
        }
      }
    }
    map.put("dayList", dayList);
    map.put("monthList", monthList);
    map.put("prValueLists", prValueLists);
    map.put("displayPrValue", displayPrValue);

    return map;
  }
}
