package com.jiayue.insu.incloud.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiayue.insu.incloud.entity.ForecastData;
import com.jiayue.insu.incloud.entity.MonthPowerGeneration;
import com.jiayue.insu.incloud.entity.PowerGeneration;
import com.jiayue.insu.incloud.entity.PowerStationStatusData;
import com.jiayue.insu.incloud.mapper.MonthPowerGenerationMapper;
import com.jiayue.insu.incloud.service.ForecastDataService;
import com.jiayue.insu.incloud.service.MonthPowerGenerationService;
import com.jiayue.insu.incloud.service.PowerGenerationService;
import com.jiayue.insu.incloud.service.PowerStationStatusDataService;
import com.jiayue.insu.incloud.utils.FixedCapacityList;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 发电量预测业务实现
 *
 * @author yh
 * @version 1.0
 * @since 2022/5/22 11:29
 */
@Service
@Slf4j
public class MonthPowerGenerationServiceImpl extends ServiceImpl<MonthPowerGenerationMapper, MonthPowerGeneration> implements MonthPowerGenerationService {

    @Autowired
    private PowerGenerationService powerGenerationService;


    /**
     * 计算预测发电量
     *
     * @param nowDate
     * @return
     */
    @Override
    public boolean generatePower(LocalDateTime nowDate, String stationCode) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        String changeDate = sdf.format(new Date());

        Date date = null;
        try {
            date = sdf.parse(changeDate);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        List<MonthPowerGeneration> checkList = findByGenDateAndStationCode(date,stationCode);
        if (checkList.size() > 0){
            log.info("月发电量已经生成过了，不再进行计算！");
            return true;
        }
        // 查询今天生成的日发电量
        List<PowerGeneration> powerGenerationList = powerGenerationService.findByStationCodeAndInitTime(stationCode, date);

        List<MonthPowerGeneration> monthPowerGenerationList = new ArrayList<>();

        if (powerGenerationList.size() > 0) {
            monthPowerGenerationList =  calculateMonthPowerGeneration(powerGenerationList,changeDate,stationCode,date);
        }else {
            powerGenerationService.generatePower(LocalDateTime.now(),stationCode);
            powerGenerationList = powerGenerationService.findByStationCodeAndInitTime(stationCode, date);
            monthPowerGenerationList =  calculateMonthPowerGeneration(powerGenerationList,changeDate,stationCode,date);
        }
        this.saveBatch(monthPowerGenerationList);
        return true;
    }

    @Override
    public List<MonthPowerGeneration> findByGenDateAndStationCode(Date genDate, String stationCode) {
        LambdaQueryWrapper<MonthPowerGeneration> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(MonthPowerGeneration::getGenDate,genDate);
        lambdaQueryWrapper.eq(MonthPowerGeneration::getStationCode,stationCode);
        return list(lambdaQueryWrapper);
    }

    public List<MonthPowerGeneration> calculateMonthPowerGeneration(List<PowerGeneration> powerGenerationList,String changeDate,String stationCode,Date date){
        List<MonthPowerGeneration> monthPowerGenerationList = new ArrayList<>();
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 定义日期格式化器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM");

        List<PowerGeneration> list =  powerGenerationList.stream().filter(f -> !f.getForecastTime().equals(changeDate)).collect(Collectors.toList());
        double monthValue = list.stream()
                .mapToDouble(PowerGeneration::getPredictedElectricityConsumption)
                .filter(value -> value >= 0)
                .sum();

        // 下月预测功率
        BigDecimal nextMouthVal;
        for (int i = 1; i <= 12; i++) {
            LocalDate futureMonth = currentDate.plusMonths(i);
            String formattedMonth = futureMonth.format(formatter);
            BigDecimal max = new BigDecimal(monthValue).multiply(new BigDecimal(1.2));
            BigDecimal min = new BigDecimal(monthValue).multiply(new BigDecimal(0.8));
            nextMouthVal = new BigDecimal(Math.random()).multiply(max.subtract(min)).add(min);
            MonthPowerGeneration monthPowerGeneration = new MonthPowerGeneration();
            monthPowerGeneration.setStationCode(stationCode);
            monthPowerGeneration.setForecastTime(formattedMonth);
            monthPowerGeneration.setPredictedElectricityConsumption(nextMouthVal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
            monthPowerGeneration.setGenDate(date);
            monthPowerGenerationList.add(monthPowerGeneration);
        }
        return monthPowerGenerationList;
    }
}
