/*
 * 文 件 名:  TaskService
 * 版    权:  华设设计集团股份有限公司
 * 描    述:  <描述>
 * 修 改 人:  lvwenbin
 * 修改时间:  2025/5/22
 * 跟踪单号:  <跟踪单号>
 * 修改单号:  <修改单号>
 * 修改内容:  <修改内容>
 */
package com.ruoyi.ems.task;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.huashe.common.domain.model.DateAttr;
import com.huashe.common.domain.model.WeatherForecast;
import com.huashe.common.domain.model.WeatherRt;
import com.huashe.common.exception.Assert;
import com.huashe.common.utils.HttpUtils;
import com.ruoyi.ems.config.AnalysisConfig;
import com.ruoyi.ems.config.DateAttrConfig;
import com.ruoyi.ems.config.WeatherConfig;
import com.ruoyi.ems.domain.EmsFacs;
import com.ruoyi.ems.model.QueryMeter;
import com.ruoyi.ems.service.IDateService;
import com.ruoyi.ems.service.IEmsFacsService;
import com.ruoyi.ems.service.IWeatherService;
import com.ruoyi.ems.service.analysis.ElecProdForecastService;
import com.ruoyi.ems.service.analysis.EmsEcoAnalysisService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.URIBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.Year;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.List;

/**
 * 调度任务
 * <功能详细描述>
 *
 * @author lvwenbin
 * @version [版本号, 2025/5/22]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Configuration
@EnableScheduling
public class TaskService {
    private static final Logger log = LoggerFactory.getLogger(TaskService.class);

    @Resource
    private IEmsFacsService facsService;

    @Resource
    private WeatherConfig weatherConfig;

    @Resource
    private DateAttrConfig holidayConfig;

    @Resource
    private IWeatherService weatherService;

    @Resource
    private IDateService dateService;

    @Resource
    private EmsEcoAnalysisService ecoAnalysisService;

    @Resource
    private ElecProdForecastService elecProdForecastService;

    @Resource
    private AnalysisConfig analysisConfig;

    /**
     * 天气实况采集
     */
    @Async
    @Scheduled(cron = "${general-data.weather.rt.cron}")
    public void collectRt() {
        log.debug("start collect weather rt.");

        try {
            URIBuilder uriBuilder = new URIBuilder(weatherConfig.getWeatherRtAddr());
            uriBuilder.addParameter("adcode", weatherConfig.getAdcode())
                .addParameter("apiKey", weatherConfig.getApiKey());
            String res = HttpUtils.doGet(uriBuilder);
            log.debug("get res:\r\n{}", res);

            JSONObject jsonObject = JSON.parseObject(res);

            String code = jsonObject.getString("code");
            Assert.isTrue(StringUtils.equals(code, "0"), -1, jsonObject.getString("message"));

            String data = jsonObject.getString("data");

            if (data != null) {
                WeatherRt weatherRt = JSONObject.parseObject(data, WeatherRt.class);
                weatherService.mergeRt(weatherRt);
            }
        }
        catch (Exception e) {
            log.error("collectRt fail!", e);
        }
    }

    /**
     * 天气预报采集
     */
    @Async
    @Scheduled(cron = "${general-data.weather.forecast.cron}")
    public void collectForecast() {
        log.debug("start collect weather forecast.");

        try {
            URIBuilder uriBuilder = new URIBuilder(weatherConfig.getWeatherForecastAddr());
            uriBuilder.addParameter("adcode", weatherConfig.getAdcode())
                .addParameter("apiKey", weatherConfig.getApiKey());
            String res = HttpUtils.doGet(uriBuilder);
            log.debug("get res:\r\n{}", res);

            JSONObject jsonObject = JSON.parseObject(res);

            String code = jsonObject.getString("code");
            Assert.isTrue(StringUtils.equals(code, "0"), -1, jsonObject.getString("message"));

            JSONArray data = jsonObject.getJSONArray("data");
            Assert.notNull(data, -1, "weather list is null.");

            if (!data.isEmpty()) {
                List<WeatherForecast> forecastList = JSON.parseArray(data.toString(), WeatherForecast.class);

                if (CollectionUtils.isNotEmpty(forecastList)) {
                    weatherService.deleteForecastByAdcode(weatherConfig.getAdcode());
                    weatherService.insertForecastBacth(forecastList);
                }
            }
        }
        catch (Exception e) {
            log.error("collectForecast fail!", e);
        }
    }

    /**
     * 节假日采集
     */
    @Async
    @Scheduled(cron = "${general-data.date.cron}")
    public void collectDateAttr() {
        log.debug("start collect date attr.");

        try {
            // 获取当前年份
            int currentYear = Year.now().getValue();

            // 本年第一天
            LocalDate firstDay = LocalDate.of(currentYear, 1, 1);

            // 本年最后一天（12月31日）
            LocalDate lastDay = LocalDate.of(currentYear, 12, 31);

            // 定义日期格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

            URIBuilder uriBuilder = new URIBuilder(holidayConfig.getApiAddr());
            uriBuilder.addParameter("startDate", formatter.format(firstDay))
                .addParameter("endDate", formatter.format(lastDay)).addParameter("apiKey", weatherConfig.getApiKey());
            String res = HttpUtils.doGet(uriBuilder);
            log.debug("get res:\r\n{}", res);

            JSONObject jsonObject = JSON.parseObject(res);

            String code = jsonObject.getString("code");
            Assert.isTrue(StringUtils.equals(code, "0"), -1, jsonObject.getString("message"));

            JSONArray data = jsonObject.getJSONArray("data");
            Assert.notNull(data, -1, "date attr is null.");

            if (!data.isEmpty()) {
                List<DateAttr> dateAttrs = JSON.parseArray(data.toString(), DateAttr.class);

                if (CollectionUtils.isNotEmpty(dateAttrs)) {
                    dateService.deleteByYear(String.valueOf(currentYear));
                    dateService.insertBatch(dateAttrs);
                }
            }
        }
        catch (Exception e) {
            log.error("collect date attr fail!", e);
        }
    }

    /**
     * 节能分析
     */
    @Async
    @Scheduled(cron = "${analysis-task.eco-analysis.cron}")
    public void triggerEcoAnalysis() {
        log.debug("start eco analysis task.");
        DateTimeFormatter dateForm = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        try {
            // 获取今天的日期
            LocalDate today = LocalDate.now();
            LocalDate yesterday = today.minusDays(1);
            String date = yesterday.format(dateForm);

            String[] areaCodes = analysisConfig.getEcoAnalysisAreas();

            if (ArrayUtils.isNotEmpty(areaCodes)) {
                // 获取上个月的日期
                LocalDate lastMonth = today.minusMonths(1);

                // 获取上个月的第一天
                LocalDate firstDayOfLastMonth = lastMonth.withDayOfMonth(1);

                // 获取上个月的最后一天
                LocalDate lastDayOfLastMonth = lastMonth.with(TemporalAdjusters.lastDayOfMonth());

                for (String areaCode : areaCodes) {
                    QueryMeter queryMeter = new QueryMeter();
                    queryMeter.setAreaCode(areaCode);
                    queryMeter.setStartRecTime(firstDayOfLastMonth.format(dateForm));
                    queryMeter.setEndRecTime(lastDayOfLastMonth.format(dateForm));

                    ecoAnalysisService.executePvForecast(areaCode, date, queryMeter);
                }
            }
        }
        catch (Exception e) {
            log.error("eco analysis fail!", e);
        }
    }

    /**
     * 光伏发电预测
     */
    @Async
    @Scheduled(cron = "${analysis-task.pv-forecast.cron}")
    public void pvForecastTask() {
        log.debug("start pv forecast task.");

        try {
            // 获取今天的日期
            LocalDate today = LocalDate.now();
            String[] areaCodes = analysisConfig.getPvForecastAreas();

            if (ArrayUtils.isNotEmpty(areaCodes)) {
                String adcode = analysisConfig.getAdcode();
                int prodForecastDays = analysisConfig.getProdForecastDays();

                for (String areaCode : areaCodes) {
                    EmsFacs param = new EmsFacs();
                    param.setRefArea(areaCode);
                    param.setFacsCategory("E");
                    List<EmsFacs> facsList = facsService.selectEmsFacsList(param);

                    if (CollectionUtils.isNotEmpty(facsList)) {
                        for (EmsFacs facs : facsList) {
                            elecProdForecastService.executePvForecast(adcode, areaCode, facs.getFacsCode(), today,
                                prodForecastDays);
                        }
                    }
                }
            }
        }
        catch (Exception e) {
            log.error("pv forecast fail!", e);
        }
    }

    /**
     * 用电预测
     */
    @Async
    @Scheduled(cron = "${analysis-task.pv-forecast.cron}")
    public void elecConsumeForecastTask() {

    }
}