package com.example.demo.service;

import com.example.demo.model.*;
import com.example.demo.repository.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

/**
 * 任务清理服务
 * 负责定期清理任务列表，将成功任务导出到归档表，删除失败任务
 */
@Service
@Transactional
public class TaskCleanupService {
    
    private static final Logger logger = LoggerFactory.getLogger(TaskCleanupService.class);
    
    @Autowired
    private TaskQueueRepository taskQueueRepository;
    
    @Autowired
    private TextToVideoTaskRepository textToVideoTaskRepository;
    
    @Autowired
    private ImageToVideoTaskRepository imageToVideoTaskRepository;
    
    @Autowired
    private CompletedTaskArchiveRepository completedTaskArchiveRepository;
    
    @Autowired
    private FailedTaskCleanupLogRepository failedTaskCleanupLogRepository;
    
    @Value("${task.cleanup.retention-days:30}")
    private int retentionDays;
    
    @Value("${task.cleanup.archive-retention-days:365}")
    private int archiveRetentionDays;
    
    /**
     * 执行完整的任务清理
     * 1. 导出成功任务到归档表
     * 2. 记录失败任务到清理日志
     * 3. 删除原始任务记录
     */
    public Map<String, Object> performFullCleanup() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            logger.info("开始执行完整任务清理...");
            
            // 1. 清理文生视频任务
            Map<String, Object> textCleanupResult = cleanupTextToVideoTasks();
            
            // 2. 清理图生视频任务
            Map<String, Object> imageCleanupResult = cleanupImageToVideoTasks();
            
            // 3. 清理任务队列
            Map<String, Object> queueCleanupResult = cleanupTaskQueue();
            
            // 4. 清理过期的归档记录
            Map<String, Object> archiveCleanupResult = cleanupExpiredArchives();
            
            // 汇总结果
            result.put("success", true);
            result.put("message", "任务清理完成");
            result.put("textToVideo", textCleanupResult);
            result.put("imageToVideo", imageCleanupResult);
            result.put("taskQueue", queueCleanupResult);
            result.put("archiveCleanup", archiveCleanupResult);
            
            logger.info("任务清理完成: {}", result);
            
        } catch (Exception e) {
            logger.error("任务清理失败", e);
            result.put("success", false);
            result.put("message", "任务清理失败: " + e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 清理文生视频任务
     */
    private Map<String, Object> cleanupTextToVideoTasks() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 查找已完成的任务
            List<TextToVideoTask> completedTasks = textToVideoTaskRepository.findByStatus(TextToVideoTask.TaskStatus.COMPLETED);
            
            // 查找失败的任务
            List<TextToVideoTask> failedTasks = textToVideoTaskRepository.findByStatus(TextToVideoTask.TaskStatus.FAILED);
            
            int archivedCount = 0;
            int cleanedCount = 0;
            
            // 导出成功任务到归档表
            for (TextToVideoTask task : completedTasks) {
                try {
                    CompletedTaskArchive archive = CompletedTaskArchive.fromTextToVideoTask(task);
                    completedTaskArchiveRepository.save(archive);
                    archivedCount++;
                } catch (Exception e) {
                    logger.error("归档文生视频任务失败: {}", task.getTaskId(), e);
                }
            }
            
            // 记录失败任务到清理日志
            for (TextToVideoTask task : failedTasks) {
                try {
                    FailedTaskCleanupLog log = FailedTaskCleanupLog.fromTextToVideoTask(task);
                    failedTaskCleanupLogRepository.save(log);
                    cleanedCount++;
                } catch (Exception e) {
                    logger.error("记录失败文生视频任务日志失败: {}", task.getTaskId(), e);
                }
            }
            
            // 删除原始任务记录
            if (!completedTasks.isEmpty()) {
                textToVideoTaskRepository.deleteAll(completedTasks);
            }
            if (!failedTasks.isEmpty()) {
                textToVideoTaskRepository.deleteAll(failedTasks);
            }
            
            result.put("archived", archivedCount);
            result.put("cleaned", cleanedCount);
            result.put("total", archivedCount + cleanedCount);
            
            logger.info("文生视频任务清理完成: 归档{}个, 清理{}个", archivedCount, cleanedCount);
            
        } catch (Exception e) {
            logger.error("清理文生视频任务失败", e);
            result.put("error", e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 清理图生视频任务
     */
    private Map<String, Object> cleanupImageToVideoTasks() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 查找已完成的任务
            List<ImageToVideoTask> completedTasks = imageToVideoTaskRepository.findByStatus(ImageToVideoTask.TaskStatus.COMPLETED);
            
            // 查找失败的任务
            List<ImageToVideoTask> failedTasks = imageToVideoTaskRepository.findByStatus(ImageToVideoTask.TaskStatus.FAILED);
            
            int archivedCount = 0;
            int cleanedCount = 0;
            
            // 导出成功任务到归档表
            for (ImageToVideoTask task : completedTasks) {
                try {
                    CompletedTaskArchive archive = CompletedTaskArchive.fromImageToVideoTask(task);
                    completedTaskArchiveRepository.save(archive);
                    archivedCount++;
                } catch (Exception e) {
                    logger.error("归档图生视频任务失败: {}", task.getTaskId(), e);
                }
            }
            
            // 记录失败任务到清理日志
            for (ImageToVideoTask task : failedTasks) {
                try {
                    FailedTaskCleanupLog log = FailedTaskCleanupLog.fromImageToVideoTask(task);
                    failedTaskCleanupLogRepository.save(log);
                    cleanedCount++;
                } catch (Exception e) {
                    logger.error("记录失败图生视频任务日志失败: {}", task.getTaskId(), e);
                }
            }
            
            // 删除原始任务记录
            if (!completedTasks.isEmpty()) {
                imageToVideoTaskRepository.deleteAll(completedTasks);
            }
            if (!failedTasks.isEmpty()) {
                imageToVideoTaskRepository.deleteAll(failedTasks);
            }
            
            result.put("archived", archivedCount);
            result.put("cleaned", cleanedCount);
            result.put("total", archivedCount + cleanedCount);
            
            logger.info("图生视频任务清理完成: 归档{}个, 清理{}个", archivedCount, cleanedCount);
            
        } catch (Exception e) {
            logger.error("清理图生视频任务失败", e);
            result.put("error", e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 清理任务队列
     */
    private Map<String, Object> cleanupTaskQueue() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 查找已完成和失败的任务队列记录
            List<TaskQueue> completedQueues = taskQueueRepository.findByStatus(TaskQueue.QueueStatus.COMPLETED);
            List<TaskQueue> failedQueues = taskQueueRepository.findByStatus(TaskQueue.QueueStatus.FAILED);
            
            int cleanedCount = completedQueues.size() + failedQueues.size();
            
            // 删除已完成的任务队列记录
            if (!completedQueues.isEmpty()) {
                taskQueueRepository.deleteAll(completedQueues);
            }
            
            // 删除失败的任务队列记录
            if (!failedQueues.isEmpty()) {
                taskQueueRepository.deleteAll(failedQueues);
            }
            
            result.put("cleaned", cleanedCount);
            
            logger.info("任务队列清理完成: 清理{}个记录", cleanedCount);
            
        } catch (Exception e) {
            logger.error("清理任务队列失败", e);
            result.put("error", e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 清理过期的归档记录
     */
    private Map<String, Object> cleanupExpiredArchives() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            LocalDateTime cutoffDate = LocalDateTime.now().minusDays(archiveRetentionDays);
            
            // 清理过期的成功任务归档
            int archivedCleaned = completedTaskArchiveRepository.deleteOlderThan(cutoffDate);
            
            // 清理过期的失败任务清理日志
            int logCleaned = failedTaskCleanupLogRepository.deleteOlderThan(cutoffDate);
            
            result.put("archivedCleaned", archivedCleaned);
            result.put("logCleaned", logCleaned);
            result.put("total", archivedCleaned + logCleaned);
            
            logger.info("过期归档清理完成: 归档记录{}个, 日志记录{}个", archivedCleaned, logCleaned);
            
        } catch (Exception e) {
            logger.error("清理过期归档失败", e);
            result.put("error", e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 获取清理统计信息
     */
    @Transactional(readOnly = true)
    public Map<String, Object> getCleanupStats() {
        Map<String, Object> stats = new HashMap<>();
        
        try {
            // 当前任务统计
            long totalTextTasks = textToVideoTaskRepository.count();
            long completedTextTasks = textToVideoTaskRepository.findByStatus(TextToVideoTask.TaskStatus.COMPLETED).size();
            long failedTextTasks = textToVideoTaskRepository.findByStatus(TextToVideoTask.TaskStatus.FAILED).size();
            
            long totalImageTasks = imageToVideoTaskRepository.count();
            long completedImageTasks = imageToVideoTaskRepository.findByStatus(ImageToVideoTask.TaskStatus.COMPLETED).size();
            long failedImageTasks = imageToVideoTaskRepository.findByStatus(ImageToVideoTask.TaskStatus.FAILED).size();
            
            long totalQueueTasks = taskQueueRepository.count();
            long completedQueueTasks = taskQueueRepository.findByStatus(TaskQueue.QueueStatus.COMPLETED).size();
            long failedQueueTasks = taskQueueRepository.findByStatus(TaskQueue.QueueStatus.FAILED).size();
            
            // 归档统计
            long totalArchived = completedTaskArchiveRepository.count();
            long totalCleanupLogs = failedTaskCleanupLogRepository.count();
            
            stats.put("currentTasks", Map.of(
                "textToVideo", Map.of("total", totalTextTasks, "completed", completedTextTasks, "failed", failedTextTasks),
                "imageToVideo", Map.of("total", totalImageTasks, "completed", completedImageTasks, "failed", failedImageTasks),
                "taskQueue", Map.of("total", totalQueueTasks, "completed", completedQueueTasks, "failed", failedQueueTasks)
            ));
            
            stats.put("archives", Map.of(
                "completedTasks", totalArchived,
                "cleanupLogs", totalCleanupLogs
            ));
            
            stats.put("config", Map.of(
                "retentionDays", retentionDays,
                "archiveRetentionDays", archiveRetentionDays
            ));
            
        } catch (Exception e) {
            logger.error("获取清理统计信息失败", e);
            stats.put("error", e.getMessage());
        }
        
        return stats;
    }
    
    /**
     * 手动清理指定用户的任务
     */
    public Map<String, Object> cleanupUserTasks(String username) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 清理用户的文生视频任务
            List<TextToVideoTask> userTextTasks = textToVideoTaskRepository.findByUsernameOrderByCreatedAtDesc(username);
            int textArchived = 0;
            int textCleaned = 0;
            
            for (TextToVideoTask task : userTextTasks) {
                if (task.getStatus() == TextToVideoTask.TaskStatus.COMPLETED) {
                    CompletedTaskArchive archive = CompletedTaskArchive.fromTextToVideoTask(task);
                    completedTaskArchiveRepository.save(archive);
                    textArchived++;
                } else if (task.getStatus() == TextToVideoTask.TaskStatus.FAILED) {
                    FailedTaskCleanupLog log = FailedTaskCleanupLog.fromTextToVideoTask(task);
                    failedTaskCleanupLogRepository.save(log);
                    textCleaned++;
                }
            }
            
            // 清理用户的图生视频任务
            List<ImageToVideoTask> userImageTasks = imageToVideoTaskRepository.findByUsernameOrderByCreatedAtDesc(username);
            int imageArchived = 0;
            int imageCleaned = 0;
            
            for (ImageToVideoTask task : userImageTasks) {
                if (task.getStatus() == ImageToVideoTask.TaskStatus.COMPLETED) {
                    CompletedTaskArchive archive = CompletedTaskArchive.fromImageToVideoTask(task);
                    completedTaskArchiveRepository.save(archive);
                    imageArchived++;
                } else if (task.getStatus() == ImageToVideoTask.TaskStatus.FAILED) {
                    FailedTaskCleanupLog log = FailedTaskCleanupLog.fromImageToVideoTask(task);
                    failedTaskCleanupLogRepository.save(log);
                    imageCleaned++;
                }
            }
            
            // 删除原始任务记录
            if (!userTextTasks.isEmpty()) {
                textToVideoTaskRepository.deleteAll(userTextTasks);
            }
            if (!userImageTasks.isEmpty()) {
                imageToVideoTaskRepository.deleteAll(userImageTasks);
            }
            
            result.put("success", true);
            result.put("message", "用户任务清理完成");
            result.put("textToVideo", Map.of("archived", textArchived, "cleaned", textCleaned));
            result.put("imageToVideo", Map.of("archived", imageArchived, "cleaned", imageCleaned));
            
            logger.info("用户{}任务清理完成: 文生视频归档{}个清理{}个, 图生视频归档{}个清理{}个", 
                       username, textArchived, textCleaned, imageArchived, imageCleaned);
            
        } catch (Exception e) {
            logger.error("清理用户{}任务失败", username, e);
            result.put("success", false);
            result.put("message", "清理用户任务失败: " + e.getMessage());
        }
        
        return result;
    }
}
