package com.qqchen.deploy.backend.schedule.job;

import com.qqchen.deploy.backend.schedule.service.JobProgressReporter;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 * 定时任务抽象基类
 * 封装了公共的进度报告和日志记录逻辑
 * 
 * 使用方式：
 * 1. 继承此类
 * 2. 实现 doExecute() 方法
 * 3. 使用 updateProgress() 报告进度
 * 4. 添加 @Component 注解并指定bean名称
 *
 * @author qichen
 */
@Slf4j
public abstract class AbstractScheduleJob implements IScheduleJob {

    @Resource
    protected JobProgressReporter progressReporter;

    /**
     * 执行任务（模板方法）
     * 统一处理进度报告、异常捕获等
     */
    @Override
    public final void execute(Map<String, Object> params) throws Exception {
        log.info("开始执行定时任务: {} - {}", getJobName(), getJobDescription());
        
        try {
            // 执行前处理
            beforeExecute(params);
            
            // 报告开始状态
            if (supportProgress()) {
                updateProgress(0, "任务开始执行");
            }
            
            // 执行核心业务逻辑
            doExecute(params);
            
            // 报告完成状态
            if (supportProgress()) {
                updateProgress(100, "任务执行完成");
            }
            
            // 执行后处理
            afterExecute(params, true);
            
            log.info("定时任务执行完成: {}", getJobName());
            
        } catch (Exception e) {
            log.error("定时任务执行失败: {}", getJobName(), e);
            afterExecute(params, false);
            throw e;
        }
    }

    /**
     * 核心业务逻辑实现
     * 子类必须实现此方法
     *
     * @param params 任务参数
     * @throws Exception 执行异常
     */
    protected abstract void doExecute(Map<String, Object> params) throws Exception;

    /**
     * 更新任务进度
     *
     * @param progress 进度百分比 (0-100)
     * @param message 进度消息
     */
    protected void updateProgress(int progress, String message) {
        if (progressReporter != null) {
            progressReporter.updateProgress(progress, message);
        }
    }

    /**
     * 从参数中获取值
     *
     * @param params 参数Map
     * @param key 参数键
     * @param defaultValue 默认值
     * @param <T> 值类型
     * @return 参数值
     */
    @SuppressWarnings("unchecked")
    protected <T> T getParam(Map<String, Object> params, String key, T defaultValue) {
        if (params == null || !params.containsKey(key)) {
            return defaultValue;
        }
        try {
            return (T) params.get(key);
        } catch (ClassCastException e) {
            log.warn("参数类型转换失败: {} = {}, 使用默认值: {}", key, params.get(key), defaultValue);
            return defaultValue;
        }
    }

    /**
     * 从参数中获取必填值
     *
     * @param params 参数Map
     * @param key 参数键
     * @param <T> 值类型
     * @return 参数值
     * @throws IllegalArgumentException 如果参数不存在
     */
    @SuppressWarnings("unchecked")
    protected <T> T getRequiredParam(Map<String, Object> params, String key) {
        if (params == null || !params.containsKey(key)) {
            throw new IllegalArgumentException("缺少必填参数: " + key);
        }
        return (T) params.get(key);
    }

    @Override
    public boolean supportProgress() {
        return true; // 默认支持进度报告
    }
}

