package com.dora.controller;

import com.dora.common.Result;
import com.dora.service.RunningHubQueueService;
import com.dora.service.impl.RunningHubQueueServiceImpl;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * RunningHub队列管理接口（管理员）
 * 
 * @author 1818AI
 * @since 2025-10-20
 */
@Slf4j
@RestController
@RequestMapping("/admin/runninghub/queue")
@RequiredArgsConstructor
@Tag(name = "管理员 - RunningHub队列管理", description = "查看和管理RunningHub任务队列状态")
public class AdminRunningHubQueueController {

    private final RunningHubQueueService runningHubQueueService;
    private final RunningHubQueueServiceImpl runningHubQueueServiceImpl;

    @Value("${ai.providers.runninghub.max-polling-tasks:100}")
    private int maxPollingTasks;

    /**
     * 获取RunningHub队列状态
     */
    @GetMapping("/status")
    @PreAuthorize("hasRole('ADMIN')")
    @Operation(summary = "获取RunningHub队列状态", description = "查看当前正在轮询的任务数和等待队列长度")
    public Result<Map<String, Object>> getQueueStatus() {
        try {
            int pollingCount = runningHubQueueService.getPollingTaskCount();
            int waitingCount = runningHubQueueService.getWaitingQueueSize();
            
            Map<String, Object> status = new HashMap<>();
            status.put("maxPollingTasks", maxPollingTasks);
            status.put("currentPollingTasks", pollingCount);
            status.put("waitingQueueSize", waitingCount);
            status.put("availableSlots", maxPollingTasks - pollingCount);
            status.put("utilizationRate", String.format("%.1f%%", (pollingCount * 100.0 / maxPollingTasks)));
            
            // 如果实现类有getPollingTaskNos方法，获取正在轮询的任务列表
            try {
                Set<String> pollingTaskNos = runningHubQueueServiceImpl.getPollingTaskNos();
                status.put("pollingTaskNos", pollingTaskNos);
            } catch (Exception e) {
                log.debug("无法获取轮询任务列表", e);
            }
            
            log.info("管理员查询RunningHub队列状态 - 轮询: {}/{}, 等待: {}", 
                     pollingCount, maxPollingTasks, waitingCount);
            
            return Result.success(status);
        } catch (Exception e) {
            log.error("获取RunningHub队列状态失败", e);
            return Result.error(500, "获取队列状态失败: " + e.getMessage());
        }
    }

    /**
     * 手动处理等待队列（管理员操作）
     */
    @GetMapping("/process")
    @PreAuthorize("hasRole('ADMIN')")
    @Operation(summary = "手动处理等待队列", description = "手动触发等待队列处理，提交等待中的任务")
    public Result<Map<String, Object>> processQueue() {
        try {
            int beforePolling = runningHubQueueService.getPollingTaskCount();
            int beforeWaiting = runningHubQueueService.getWaitingQueueSize();
            
            int submitted = runningHubQueueService.processWaitingQueue();
            
            int afterPolling = runningHubQueueService.getPollingTaskCount();
            int afterWaiting = runningHubQueueService.getWaitingQueueSize();
            
            Map<String, Object> result = new HashMap<>();
            result.put("submittedTasks", submitted);
            result.put("beforePolling", beforePolling);
            result.put("afterPolling", afterPolling);
            result.put("beforeWaiting", beforeWaiting);
            result.put("afterWaiting", afterWaiting);
            
            log.info("管理员手动处理RunningHub队列 - 提交了{}个任务", submitted);
            
            return Result.success(result, "已处理等待队列，提交了" + submitted + "个任务");
        } catch (Exception e) {
            log.error("手动处理RunningHub队列失败", e);
            return Result.error(500, "处理队列失败: " + e.getMessage());
        }
    }
}

