package com.cpp.web.service.accuracy.impl;

import com.cpp.common.utils.spring.SpringUtils;
import com.cpp.system.service.ISysConfigService;
import com.cpp.web.domain.accuracy.AccuracyPassRate;
import com.cpp.web.domain.cloud.ForecastPowerUltraShortTermCloud;
import com.cpp.web.domain.enums.DataSourcesEnum;
import com.cpp.web.domain.enums.ForecastTypeEnum;
import com.cpp.web.domain.station.ElectricField;
import com.cpp.web.domain.station.ForecastPowerUltraShortTermStation;
import com.cpp.web.domain.station.PowerStationStatusData;
import com.cpp.web.service.accuracy.CalculateInterface;
import com.cpp.web.service.cloud.ForecastPowerUltraShortTermCloudService;
import com.cpp.web.service.station.ForecastPowerUltraShortTermStationService;
import com.syjy.calculate.entity.CalculateRequest;
import com.syjy.calculate.entity.CalculateResult;
import com.syjy.calculate.entity.CalculationFormula;
import com.syjy.calculate.entity.CalculationInfo;
import com.syjy.calculate.service.AccuracyPassRateCalculateService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

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

/**
 * 计算中心测超短期预测分析结果
 */
@RequiredArgsConstructor
@Service
public class CalculateForecastPowerUltraShortTermCloudImpl implements CalculateInterface {
    private final ISysConfigService sysConfigService;
    private final ForecastPowerUltraShortTermCloudService forecastPowerUltraShortTermCloudService;

    @Override
    public List<AccuracyPassRate> calc(Date startTime, Date endTime, List<PowerStationStatusData> powerStationStatusDataList, List<ElectricField> electricFieldList, List<String> formulaTypes, String province) {

        List<AccuracyPassRate> accuracyPassRates = new ArrayList<>();
        String cdq_ac_point = sysConfigService.selectConfigByKey("cdqHowLongAgo");
        int ago = 1;
        try {
            ago = Integer.parseInt(cdq_ac_point);
        } catch (Exception e) {
//            e.printStackTrace();
        }


        List<ForecastPowerUltraShortTermCloud> forecastPowerUltraShortTermCloudList = forecastPowerUltraShortTermCloudService.findByForecastTimeBetweenAndHowLongAgo(startTime, endTime, ago);

        for (ElectricField electricField : electricFieldList) {
            // 获取装机容量
            BigDecimal capacity = electricField.getCapacity();
            // 获取场站编码
            String stationCode = electricField.getStationCode();
            // 场站类型
            String electricType = electricField.getElectricFieldTypeEnum();

            AccuracyPassRate accuracyPassRate = new AccuracyPassRate();
            accuracyPassRate.setTime(startTime);
            accuracyPassRate.setDataSources(DataSourcesEnum.E2);
            accuracyPassRate.setForecastType(ForecastTypeEnum.cdq);
            accuracyPassRate.setStationCode(stationCode);
            accuracyPassRate.setForecastHowLongAgo(ago);


            // 获取实际功率
            Map<Date, List<ForecastPowerUltraShortTermCloud>> dateForecastListMap = forecastPowerUltraShortTermCloudList.stream().filter(p -> p.getStationCode().equals(stationCode)).collect(Collectors.groupingBy(ForecastPowerUltraShortTermCloud::getTime, Collectors.toList()));
            // 短期预测功率
            Map<Date, List<PowerStationStatusData>> datePowerListMap = powerStationStatusDataList.stream().filter(f -> f.getStationCode().equals(stationCode)).collect(Collectors.groupingBy(PowerStationStatusData::getTime, Collectors.toList()));
            //解析中目前不带 开机和装机容量，无法计算准确率，先用场站容量代替
            BigDecimal cap = electricField.getCapacity();

            if (formulaTypes.contains("POINT_ULTRA_SHORT_ACCURACY")) {
                List<CalculationInfo> calculationInfoList = new ArrayList<>();
                // 从开始时间，每隔15分钟，一直循环到当前时间
                for (long stepTime = startTime.getTime(); stepTime <= endTime.getTime(); stepTime += 900000L) {
                    Date finalTime = new Date(stepTime);
                    // 组装数据
                    CalculationInfo calculationInfo = new CalculationInfo();
                    // 如果短期预测功率不为空且站场功率不为空
                    if (dateForecastListMap.containsKey(finalTime) && datePowerListMap.containsKey(finalTime)) {

                        PowerStationStatusData powerStationStatusData = datePowerListMap.get(finalTime).get(0);

                        //限电时不参与考核，抛去
                        if (!powerStationStatusData.getPowerRationing().equals(1)) {
                            //实际
                            calculationInfo.setCapacity(cap);
                            calculationInfo.setOpenCapacity(cap);
                            calculationInfo.setRealValue(powerStationStatusData.getRealValue());
                            calculationInfo.setAbleValue(powerStationStatusData.getAbleValue());
                            calculationInfo.setTheoryValue(powerStationStatusData.getTheoryValue());


                            ForecastPowerUltraShortTermCloud forecastPowerUltraShortTermStation = dateForecastListMap.get(finalTime).get(0);
                            // 短期预测功率
                            calculationInfo.setTime(stepTime);
                            calculationInfo.setForecastAbleValue(forecastPowerUltraShortTermStation.getFpValue());
                            calculationInfo.setForecastTheoryValue(forecastPowerUltraShortTermStation.getFpValue());
                            calculationInfo.setForecastCapacity(cap);
                            calculationInfo.setForecastSuCapacity(cap);
                        }
                    }

                    // 预测功率或实际功率为空的时候，不放入result中
                    if (calculationInfo.getRealValue() != null && calculationInfo.getAbleValue() != null && calculationInfo.getForecastAbleValue() != null) {
                        calculationInfoList.add(calculationInfo);
                    }
                }


                if (calculationInfoList == null || calculationInfoList.size() == 0) {
                    accuracyPassRate.setAccuracy("无可用数据计算");
                    accuracyPassRates.add(accuracyPassRate);
                    continue;
                }
                // 获取计算基础数据
                CalculateRequest calculateRequest = new CalculateRequest();
                calculateRequest.setCalculationInfoList(calculationInfoList);
                calculateRequest.setElectricCapacity(capacity);
                calculateRequest.setProvince(province);
                calculateRequest.setStationCode(stationCode);
                calculateRequest.setFormulaType("POINT_ULTRA_SHORT_ACCURACY");
                calculateRequest.setElectricType(electricType);
                calculateRequest.setSign(electricField.getStationCode());
                calculateRequest.setStationStatus("无");
                calculateRequest.setStationCode(electricField.getStationCode());
                CalculateResult resultMap = SpringUtils.getBean(AccuracyPassRateCalculateService.class).calculate(calculateRequest);
                // 如果计算成功，从结果中获取value
                if (String.valueOf(resultMap.get(CalculateResult.CODE_TAG)).
                        equals(CalculateResult.Type.SUCCESS.value())) {
                    accuracyPassRate.setAccuracy(String.valueOf(resultMap.get(CalculateResult.DATA_TAG)));
                } else {
                    accuracyPassRate.setAccuracy(String.valueOf(resultMap.get(CalculateResult.MSG_TAG)));
                }

                accuracyPassRates.add(accuracyPassRate);
            }

        }
        return accuracyPassRates;
    }

    //    @Override
    public List<String> calculationTypes() {
        return Arrays.asList("POINT_ULTRA_SHORT_ACCURACY");
    }
}
