package com.dora.controller;

import com.dora.common.Result;
import com.dora.dto.AiTaskDto;
import com.dora.entity.AiTask;
import com.dora.service.AiTaskService;
import com.dora.scheduler.QueuedTaskTimeoutChecker;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 管理端 - AI任务管理控制器
 * 
 * 提供以下功能：
 * 1. 查询所有用户的AI任务（分页、多条件筛选）
 * 2. 查看任意任务的详细信息
 * 3. 强制取消任务
 * 
 * @author 1818AI
 * @since 2025-10-19
 */
@Slf4j
@RestController
@RequestMapping("/admin/ai/tasks")
@Tag(name = "AI任务管理", description = "管理端API - 用于监控和管理所有用户的AI生成任务")
@RequiredArgsConstructor
@PreAuthorize("hasRole('ADMIN')")
public class AdminTaskController {

    private final AiTaskService aiTaskService;
    private final QueuedTaskTimeoutChecker queuedTaskTimeoutChecker;

    /**
     * 分页查询所有AI任务
     * 
     * @param page 页码
     * @param size 每页数量
     * @param userId 用户ID筛选（可选）
     * @param status 任务状态筛选（可选）
     * @param modelName 模型名称筛选（可选）
     * @param taskNo 任务编号模糊搜索（可选）
     * @return 分页的任务列表
     */
    @GetMapping("/list")
    @Operation(
        summary = "获取所有AI任务列表（分页）", 
        description = "分页查询系统中的所有AI任务，支持按用户ID、状态、模型名称、任务编号等条件筛选。"
    )
    public Result<PageInfo<AiTaskDto>> getAllTasks(
            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1") int page,
            @Parameter(description = "每页数量", example = "10") @RequestParam(defaultValue = "10") int size,
            @Parameter(description = "按用户ID筛选") @RequestParam(required = false) Long userId,
            @Parameter(description = "按状态筛选 (created/queued/processing/completed/failed/cancelled)") @RequestParam(required = false) String status,
            @Parameter(description = "按模型名称筛选") @RequestParam(required = false) String modelName,
            @Parameter(description = "按任务编号模糊搜索") @RequestParam(required = false) String taskNo) {

        log.info("管理员查询AI任务列表，page={}, size={}, userId={}, status={}, modelName={}, taskNo={}", 
                 page, size, userId, status, modelName, taskNo);

        PageHelper.startPage(page, size);
        List<AiTask> tasks = aiTaskService.getAllTasks(userId, status, modelName, taskNo);
        PageInfo<AiTask> pageInfo = new PageInfo<>(tasks);

        List<AiTaskDto> dtoList = tasks.stream().map(AiTaskDto::fromEntity).collect(Collectors.toList());
        PageInfo<AiTaskDto> dtoPageInfo = new PageInfo<>(dtoList);
        dtoPageInfo.setTotal(pageInfo.getTotal());
        dtoPageInfo.setPages(pageInfo.getPages());

        log.info("成功查询AI任务列表，总数: {}, 当前页数量: {}", dtoPageInfo.getTotal(), dtoList.size());

        return Result.success(dtoPageInfo);
    }

    /**
     * 获取单个任务的详细信息
     * 
     * @param taskNo 任务编号
     * @return 任务详情
     */
    @GetMapping("/{taskNo}")
    @Operation(
        summary = "获取任意单个任务详情", 
        description = "根据任务编号查询任意一个AI任务的详细信息。管理员可以查看所有用户的任务。"
    )
    public Result<AiTaskDto> getTaskDetails(
            @Parameter(description = "任务编号", required = true, example = "TASK20251019143022ABC123")
            @PathVariable String taskNo) {
        log.info("管理员查询任务详情，taskNo: {}", taskNo);
        
        // 管理员可以查询任何任务，无需用户ID校验
        AiTask task = aiTaskService.getTaskByTaskNo(taskNo, null);
        if (task == null) {
            log.warn("任务不存在，taskNo: {}", taskNo);
            return Result.error(404, "任务不存在");
        }
        
        log.info("成功查询任务详情，taskNo: {}, status: {}", taskNo, task.getStatus());
        return Result.success(AiTaskDto.fromEntity(task));
    }
    
    /**
     * 强制取消任务
     * 
     * @param taskNo 任务编号
     * @return 操作结果
     */
    @PostMapping("/{taskNo}/cancel")
    @Operation(
        summary = "强制取消一个任务", 
        description = "手动取消一个处于排队中（queued）的任务，并退还用户积分。注意：只能取消queued状态的任务，processing状态的任务无法取消。"
    )
    public Result<Void> cancelTask(
            @Parameter(description = "任务编号", required = true, example = "TASK20251019143022ABC123")
            @PathVariable String taskNo) {
        log.info("管理员尝试取消任务，taskNo: {}", taskNo);
        
        boolean success = aiTaskService.cancelTask(taskNo);
        if (success) {
            log.info("成功取消任务，taskNo: {}", taskNo);
            return Result.success(null, "任务 " + taskNo + " 已成功取消");
        } else {
            log.warn("取消任务失败，taskNo: {}", taskNo);
            return Result.error(400, "取消失败。任务可能不存在，或当前状态无法被取消（例如，已在处理中）");
        }
    }

    @PostMapping("/queue/check-timeout")
    @Operation(
        summary = "检查并清理队列超时任务", 
        description = "手动触发队列超时检查，自动取消超过设定时间的排队任务。通常由系统自动每小时执行一次，此接口用于手动触发。"
    )
    public Result<String> checkQueueTimeout() {
        log.info("管理员手动触发队列超时检查");
        
        try {
            queuedTaskTimeoutChecker.checkNow();
            return Result.success(null, "队列超时检查已完成，详情请查看日志");
        } catch (Exception e) {
            log.error("手动触发队列超时检查失败", e);
            return Result.error(500, "检查失败: " + e.getMessage());
        }
    }
}
