package com.ruoyi.notification.util;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.ruoyi.common.utils.DateUtils;

/**
 * 定时任务监控工具类
 * 
 * @author ruoyi
 * @date 2025-12-19
 */
@Component
public class TaskMonitorUtil 
{
    private static final Logger log = LoggerFactory.getLogger(TaskMonitorUtil.class);

    // 任务执行统计
    private static final Map<Long, TaskExecutionStats> taskStatsMap = new ConcurrentHashMap<>();
    
    // 任务执行历史记录（最近100条）
    private static final Map<Long, java.util.Queue<TaskExecutionRecord>> taskHistoryMap = new ConcurrentHashMap<>();
    
    private static final int MAX_HISTORY_SIZE = 100;

    /**
     * 任务执行统计信息
     */
    public static class TaskExecutionStats {
        private AtomicLong totalExecutions = new AtomicLong(0);
        private AtomicLong successExecutions = new AtomicLong(0);
        private AtomicLong failureExecutions = new AtomicLong(0);
        private volatile Date lastExecutionTime;
        private volatile Date lastSuccessTime;
        private volatile Date lastFailureTime;
        private volatile long averageExecutionTime = 0;
        private volatile long maxExecutionTime = 0;
        private volatile long minExecutionTime = Long.MAX_VALUE;

        // Getters and setters
        public long getTotalExecutions() { return totalExecutions.get(); }
        public long getSuccessExecutions() { return successExecutions.get(); }
        public long getFailureExecutions() { return failureExecutions.get(); }
        public Date getLastExecutionTime() { return lastExecutionTime; }
        public Date getLastSuccessTime() { return lastSuccessTime; }
        public Date getLastFailureTime() { return lastFailureTime; }
        public long getAverageExecutionTime() { return averageExecutionTime; }
        public long getMaxExecutionTime() { return maxExecutionTime; }
        public long getMinExecutionTime() { return minExecutionTime == Long.MAX_VALUE ? 0 : minExecutionTime; }
        
        public double getSuccessRate() {
            long total = totalExecutions.get();
            return total > 0 ? (double) successExecutions.get() / total * 100 : 0;
        }
    }

    /**
     * 任务执行记录
     */
    public static class TaskExecutionRecord {
        private Date executionTime;
        private boolean success;
        private long executionDuration;
        private String errorMessage;

        public TaskExecutionRecord(Date executionTime, boolean success, long executionDuration, String errorMessage) {
            this.executionTime = executionTime;
            this.success = success;
            this.executionDuration = executionDuration;
            this.errorMessage = errorMessage;
        }

        // Getters
        public Date getExecutionTime() { return executionTime; }
        public boolean isSuccess() { return success; }
        public long getExecutionDuration() { return executionDuration; }
        public String getErrorMessage() { return errorMessage; }
    }

    /**
     * 记录任务开始执行
     * 
     * @param taskId 任务ID
     * @return 执行开始时间戳
     */
    public static long recordTaskStart(Long taskId) {
        log.debug("任务开始执行: taskId={}", taskId);
        return System.currentTimeMillis();
    }

    /**
     * 记录任务执行完成
     * 
     * @param taskId 任务ID
     * @param startTime 开始时间戳
     * @param success 是否成功
     * @param errorMessage 错误信息（如果失败）
     */
    public static void recordTaskCompletion(Long taskId, long startTime, boolean success, String errorMessage) {
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;
        Date executionTime = new Date(startTime);

        log.debug("任务执行完成: taskId={}, success={}, duration={}ms", taskId, success, duration);

        // 更新统计信息
        TaskExecutionStats stats = taskStatsMap.computeIfAbsent(taskId, k -> new TaskExecutionStats());
        
        stats.totalExecutions.incrementAndGet();
        stats.lastExecutionTime = executionTime;
        
        if (success) {
            stats.successExecutions.incrementAndGet();
            stats.lastSuccessTime = executionTime;
        } else {
            stats.failureExecutions.incrementAndGet();
            stats.lastFailureTime = executionTime;
        }

        // 更新执行时间统计
        updateExecutionTimeStats(stats, duration);

        // 记录执行历史
        recordExecutionHistory(taskId, executionTime, success, duration, errorMessage);
    }

    /**
     * 获取任务执行统计信息
     * 
     * @param taskId 任务ID
     * @return 统计信息
     */
    public static TaskExecutionStats getTaskStats(Long taskId) {
        return taskStatsMap.get(taskId);
    }

    /**
     * 获取任务执行历史
     * 
     * @param taskId 任务ID
     * @return 执行历史记录
     */
    public static java.util.Queue<TaskExecutionRecord> getTaskHistory(Long taskId) {
        return taskHistoryMap.get(taskId);
    }

    /**
     * 获取所有任务的统计信息
     * 
     * @return 所有任务统计信息
     */
    public static Map<Long, TaskExecutionStats> getAllTaskStats() {
        return new HashMap<>(taskStatsMap);
    }

    /**
     * 清除任务统计信息
     * 
     * @param taskId 任务ID
     */
    public static void clearTaskStats(Long taskId) {
        taskStatsMap.remove(taskId);
        taskHistoryMap.remove(taskId);
        log.info("已清除任务统计信息: taskId={}", taskId);
    }

    /**
     * 检查任务健康状态
     * 
     * @param taskId 任务ID
     * @return 是否健康
     */
    public static boolean isTaskHealthy(Long taskId) {
        TaskExecutionStats stats = taskStatsMap.get(taskId);
        if (stats == null) {
            return true; // 没有执行记录，认为是健康的
        }

        // 检查成功率
        double successRate = stats.getSuccessRate();
        if (successRate < 80.0) { // 成功率低于80%认为不健康
            return false;
        }

        // 检查最近是否有执行
        Date lastExecution = stats.getLastExecutionTime();
        if (lastExecution != null) {
            long timeSinceLastExecution = System.currentTimeMillis() - lastExecution.getTime();
            if (timeSinceLastExecution > 24 * 60 * 60 * 1000) { // 超过24小时没有执行
                return false;
            }
        }

        return true;
    }

    /**
     * 生成任务监控报告
     * 
     * @return 监控报告
     */
    public static String generateMonitorReport() {
        StringBuilder report = new StringBuilder();
        report.append("=== 定时任务监控报告 ===\n");
        report.append("生成时间: ").append(DateUtils.getTime()).append("\n\n");

        if (taskStatsMap.isEmpty()) {
            report.append("暂无任务执行统计信息\n");
            return report.toString();
        }

        for (Map.Entry<Long, TaskExecutionStats> entry : taskStatsMap.entrySet()) {
            Long taskId = entry.getKey();
            TaskExecutionStats stats = entry.getValue();

            report.append("任务ID: ").append(taskId).append("\n");
            report.append("  总执行次数: ").append(stats.getTotalExecutions()).append("\n");
            report.append("  成功次数: ").append(stats.getSuccessExecutions()).append("\n");
            report.append("  失败次数: ").append(stats.getFailureExecutions()).append("\n");
            report.append("  成功率: ").append(String.format("%.2f%%", stats.getSuccessRate())).append("\n");
            report.append("  平均执行时间: ").append(stats.getAverageExecutionTime()).append("ms\n");
            report.append("  最大执行时间: ").append(stats.getMaxExecutionTime()).append("ms\n");
            report.append("  最小执行时间: ").append(stats.getMinExecutionTime()).append("ms\n");
            
            if (stats.getLastExecutionTime() != null) {
                report.append("  最后执行时间: ").append(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, stats.getLastExecutionTime())).append("\n");
            }
            
            report.append("  健康状态: ").append(isTaskHealthy(taskId) ? "健康" : "异常").append("\n");
            report.append("\n");
        }

        return report.toString();
    }

    /**
     * 更新执行时间统计
     */
    private static void updateExecutionTimeStats(TaskExecutionStats stats, long duration) {
        // 更新最大最小执行时间
        if (duration > stats.maxExecutionTime) {
            stats.maxExecutionTime = duration;
        }
        if (duration < stats.minExecutionTime) {
            stats.minExecutionTime = duration;
        }

        // 计算平均执行时间（简单移动平均）
        long total = stats.totalExecutions.get();
        if (total == 1) {
            stats.averageExecutionTime = duration;
        } else {
            stats.averageExecutionTime = (stats.averageExecutionTime * (total - 1) + duration) / total;
        }
    }

    /**
     * 记录执行历史
     */
    private static void recordExecutionHistory(Long taskId, Date executionTime, boolean success, long duration, String errorMessage) {
        java.util.Queue<TaskExecutionRecord> history = taskHistoryMap.computeIfAbsent(taskId, 
            k -> new java.util.concurrent.ConcurrentLinkedQueue<>());

        // 添加新记录
        history.offer(new TaskExecutionRecord(executionTime, success, duration, errorMessage));

        // 保持历史记录数量不超过限制
        while (history.size() > MAX_HISTORY_SIZE) {
            history.poll();
        }
    }
}