package com.nokia.tsl_data.service;

import com.nokia.tsl_data.properties.TslDataProperties;
import com.nokia.tsl_data.scheduling.entity.RunnableTask;
import com.nokia.tsl_data.scheduling.service.TaskScheduleService;
import com.nokia.tsl_data.util.DateFormatUtil;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.File;
import java.nio.file.Paths;
import java.time.Instant;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

/**
 * 定时任务
 */
@Slf4j
@Service
public class TaskService {

    @Autowired
    private DataWarehouseService dataWarehouseService;
    @Autowired
    private MessageService messageService;
    @Autowired
    private HighQualityDataService highQualityDataService;
    @Autowired
    private TaskScheduleService taskScheduleService;
    @Autowired
    private ReportServiceV3 reportServiceV3;
    @Autowired
    private TslDataProperties tslDataProperties;
    @Autowired
    private ManagementDetailService managementDetailService;

    /**
     * 每日定时任务 每天中午1点半执行入库任务
     */
    // 20250312 修改为 15:30执行
    @Scheduled(cron = "0 30 15 * * *")
    public void dailyWarehouseTask() {
        // 这里的时间要向前一天
        String day = DateFormatUtil.ofPattern("yyyyMMdd").format(Instant.now().plus(-1L, ChronoUnit.DAYS));
        // 调度一次 taskService.wareHouseTask(day)
        RunnableTask task = new RunnableTask()
                .setTaskId("warehouse_cron_" + day)
                .setBeanName("taskService")
                .setMethodName("warehouseTask")
                .setMethodParameter(day);
        taskScheduleService.schedule(task);
    }

    /**
     * 指定日期任务
     */
    public void warehouseTask(String day) {
        // 检查源是否具备
        String result = dataWarehouseService.checkSource(day);
        if (StringUtils.hasLength(result)) {
            // 存在异常情况，发送运维消息
            messageService.error(result);
            // 20250312 修改延时调度逻辑 超过晚上24点后不再调度
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
            LocalDate localDate = LocalDate.parse(day, formatter);
            if (ChronoUnit.DAYS.between(localDate, LocalDate.now()) > 2) {
                // 因为每天执行上一天任务，如果任务时间和当前时间差超过2天，说明任务已经超时，不再继续调度
                log.info("账期 {} 任务数据源不具备，已超时：{}", day, result);
                return;
            }
            // 延时调度，间隔一段时间后再次调度
            taskScheduleService.schedule(new RunnableTask()
                    .setTaskId("warehouse_reSchedule_" + day + "_" + System.currentTimeMillis())
                    .setBeanName("taskService")
                    .setMethodName("warehouseTask")
                    .setMethodParameter(day)
                    .setDelay(3600L));
        } else {
            try {
                // 执行入库任务
                dataWarehouseService.warehouse(day);
                // 生成HighQualityData
                highQualityDataService.generateHighQualityData(day);
                // 生成ManagementDetail
                managementDetailService.generateForDay(day);
                // 报表+截图
                generateReportV3(day);
            } catch (Exception e) {
                messageService.error("指定日期任务失败：" + e.getMessage());
                e.printStackTrace();
                throw new RuntimeException("指定日期任务失败：" + e.getMessage());
            }
        }
    }

    public void runTaskForDay(String day) {
        try {
            // 执行入库任务
            dataWarehouseService.warehouse(day);
            // 生成HighQualityData
            highQualityDataService.generateHighQualityData(day);
            // 生成ManagementDetail
            managementDetailService.generateForDay(day);
            // 报表+截图
            generateReportV3(day);
        } catch (Exception e) {
            messageService.error("指定日期任务失败：" + e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("指定日期任务失败：" + e.getMessage());
        }
    }

    /**
     * 生成第三版报表
     */
    public void generateReportV3(String day) {
        // 1. 检查文件路径
        String fileName = tslDataProperties.getOutputFileNamePrefix() + day + ".xlsx";
        File file = Paths.get(tslDataProperties.getOutputPath(), "V3", day).toFile();
        if (!file.exists()) {
            boolean mkdirs = file.mkdirs();
            System.out.println(mkdirs);
        }
        file = Paths.get(file.getAbsolutePath(), fileName).toFile();
        // 2. 生成报表
        reportServiceV3.generateReport(file, day);
        log.info("V3报表 {} 生成完成...");
        // 3. 截图
        reportServiceV3.screenShot(file, day);
        log.info("V3报表 {} 截图完成...");
        // 4. 总结
        reportServiceV3.messageToSend(file, day);
        log.info("V3报表 {} 已生成总结...");
    }

}
