package com.example.demo.service;

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

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.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.example.demo.model.TaskStatus;
import com.example.demo.repository.TaskStatusRepository;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import kong.unirest.HttpResponse;
import kong.unirest.Unirest;

@Service
public class TaskStatusPollingService {
    
    private static final Logger logger = LoggerFactory.getLogger(TaskStatusPollingService.class);
    
    @Autowired
    private TaskStatusRepository taskStatusRepository;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    @Value("${ai.api.key:ak_5f13ec469e6047d5b8155c3cc91350e2}")
    private String apiKey;
    
    @Value("${ai.api.base-url:http://116.62.4.26:8081}")
    private String apiBaseUrl;
    
    /**
     * 每2分钟执行一次轮询查询任务状态
     * 固定间隔：120000毫秒 = 2分钟
     */
    @Scheduled(fixedRate = 120000) // 2分钟 = 120000毫秒
    public void pollTaskStatuses() {
        logger.info("=== 开始执行任务状态轮询查询 (每2分钟) ===");
        
        try {
            // 查找需要轮询的任务（状态为PROCESSING且创建时间超过2分钟）
            LocalDateTime cutoffTime = LocalDateTime.now().minusMinutes(2);
            List<TaskStatus> tasksToPoll = taskStatusRepository.findTasksNeedingPolling(cutoffTime);
            
            logger.info("找到 {} 个需要轮询查询的任务", tasksToPoll.size());
            
            if (tasksToPoll.isEmpty()) {
                logger.debug("当前没有需要轮询的任务");
                return;
            }
            
            // 逐个轮询任务状态
            for (TaskStatus task : tasksToPoll) {
                try {
                    logger.info("轮询任务: taskId={}, externalTaskId={}, status={}", 
                        task.getTaskId(), task.getExternalTaskId(), task.getStatus());
                    pollTaskStatus(task);
                } catch (Exception e) {
                    logger.error("轮询任务 {} 时发生错误: {}", task.getTaskId(), e.getMessage(), e);
                }
            }
            
            // 处理超时任务
            handleTimeoutTasks();
            
            logger.info("=== 任务状态轮询查询完成 ===");
            
        } catch (Exception e) {
            logger.error("轮询任务状态时发生错误: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 轮询单个任务状态
     */
    @Transactional
    public void pollTaskStatus(TaskStatus task) {
        logger.info("轮询任务状态: taskId={}, externalTaskId={}", task.getTaskId(), task.getExternalTaskId());
        
        try {
            // 调用外部API查询状态
            HttpResponse<String> response = Unirest.get(apiBaseUrl + "/v1/videos")
                .header("Authorization", "Bearer " + apiKey)
                .queryString("task_id", task.getExternalTaskId())
                .asString();
            
            if (response.getStatus() == 200) {
                JsonNode responseJson = objectMapper.readTree(response.getBody());
                updateTaskStatus(task, responseJson);
            } else {
                logger.warn("查询任务状态失败: taskId={}, status={}, response={}", 
                    task.getTaskId(), response.getStatus(), response.getBody());
                task.incrementPollCount();
                taskStatusRepository.save(task);
            }
            
        } catch (Exception e) {
            logger.error("轮询任务状态异常: taskId={}, error={}", task.getTaskId(), e.getMessage(), e);
            task.incrementPollCount();
            taskStatusRepository.save(task);
        }
    }
    
    /**
     * 更新任务状态
     */
    private void updateTaskStatus(TaskStatus task, JsonNode responseJson) {
        try {
            // 检查base_resp状态
            JsonNode baseResp = responseJson.path("base_resp");
            if (!baseResp.isMissingNode() && baseResp.path("status_code").asInt() != 0) {
                String errorMsg = baseResp.path("status_msg").asText("Unknown error");
                task.markAsFailed(errorMsg);
                logger.warn("API返回错误: taskId={}, error={}", task.getTaskId(), errorMsg);
                taskStatusRepository.save(task);
                return;
            }
            
            String status = responseJson.path("status").asText();
            int progress = responseJson.path("progress").asInt(0);
            String resultUrl = null;
            String errorMessage = responseJson.path("error_message").asText();
            
            task.incrementPollCount();
            task.setProgress(progress);
            
            switch (status.toLowerCase()) {
                case "success":
                    // 获取file_id并获取视频URL
                    String fileId = responseJson.path("file_id").asText();
                    if (!fileId.isEmpty()) {
                        resultUrl = getVideoUrlFromFileId(fileId);
                        if (resultUrl != null) {
                            task.markAsCompleted(resultUrl);
                            logger.info("任务完成: taskId={}, resultUrl={}", task.getTaskId(), resultUrl);
                        } else {
                            task.markAsFailed("无法获取视频URL");
                            logger.warn("任务完成但无法获取视频URL: taskId={}, fileId={}", task.getTaskId(), fileId);
                        }
                    } else {
                        task.markAsFailed("任务完成但未返回文件ID");
                        logger.warn("任务完成但未返回文件ID: taskId={}", task.getTaskId());
                    }
                    break;
                    
                case "failed":
                case "error":
                    task.markAsFailed(errorMessage);
                    logger.warn("任务失败: taskId={}, error={}", task.getTaskId(), errorMessage);
                    break;
                    
                case "processing":
                case "in_progress":
                case "pending":
                    task.setStatus(TaskStatus.Status.PROCESSING);
                    logger.info("任务处理中: taskId={}, progress={}%", task.getTaskId(), progress);
                    break;
                    
                default:
                    logger.warn("未知任务状态: taskId={}, status={}", task.getTaskId(), status);
                    break;
            }
            
            taskStatusRepository.save(task);
            
        } catch (Exception e) {
            logger.error("更新任务状态时发生错误: taskId={}, error={}", task.getTaskId(), e.getMessage(), e);
        }
    }
    
    /**
     * 根据file_id获取视频URL
     */
    private String getVideoUrlFromFileId(String fileId) {
        try {
            HttpResponse<String> response = Unirest.get(apiBaseUrl + "/minimax/v1/files/retrieve")
                .header("Authorization", "Bearer " + apiKey)
                .queryString("file_id", fileId)
                .asString();
            
            if (response.getStatus() == 200) {
                JsonNode responseJson = objectMapper.readTree(response.getBody());
                JsonNode fileNode = responseJson.path("file");
                if (!fileNode.isMissingNode()) {
                    String downloadUrl = fileNode.path("download_url").asText();
                    if (!downloadUrl.isEmpty()) {
                        logger.info("成功获取视频URL: fileId={}, url={}", fileId, downloadUrl);
                        return downloadUrl;
                    }
                }
            }
            
            logger.warn("获取视频URL失败: fileId={}, status={}, response={}", 
                fileId, response.getStatus(), response.getBody());
            return null;
            
        } catch (Exception e) {
            logger.error("获取视频URL时发生错误: fileId={}, error={}", fileId, e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 处理超时任务
     */
    @Transactional
    public void handleTimeoutTasks() {
        List<TaskStatus> timeoutTasks = taskStatusRepository.findTimeoutTasks();
        
        for (TaskStatus task : timeoutTasks) {
            task.markAsTimeout();
            taskStatusRepository.save(task);
            logger.warn("任务超时: taskId={}, pollCount={}", task.getTaskId(), task.getPollCount());
        }
        
        if (!timeoutTasks.isEmpty()) {
            logger.info("处理了 {} 个超时任务", timeoutTasks.size());
        }
    }
    
    /**
     * 创建新的任务状态记录
     */
    @Transactional
    public TaskStatus createTaskStatus(String taskId, String username, TaskStatus.TaskType taskType, String externalTaskId) {
        TaskStatus taskStatus = new TaskStatus(taskId, username, taskType);
        taskStatus.setExternalTaskId(externalTaskId);
        taskStatus.setStatus(TaskStatus.Status.PROCESSING);
        taskStatus.setProgress(0);
        
        return taskStatusRepository.save(taskStatus);
    }
    
    /**
     * 根据任务ID获取状态
     */
    public TaskStatus getTaskStatus(String taskId) {
        return taskStatusRepository.findByTaskId(taskId).orElse(null);
    }
    
    /**
     * 获取用户的所有任务状态
     */
    public List<TaskStatus> getUserTaskStatuses(String username) {
        return taskStatusRepository.findByUsernameOrderByCreatedAtDesc(username);
    }
    
    /**
     * 取消任务
     */
    @Transactional
    public boolean cancelTask(String taskId, String username) {
        TaskStatus task = taskStatusRepository.findByTaskId(taskId).orElse(null);
        
        if (task == null || !task.getUsername().equals(username)) {
            return false;
        }
        
        if (task.getStatus() == TaskStatus.Status.PROCESSING) {
            task.setStatus(TaskStatus.Status.CANCELLED);
            task.setUpdatedAt(LocalDateTime.now());
            taskStatusRepository.save(task);
            return true;
        }
        
        return false;
    }
}

