package org.dromara.ai.controller.app;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.ai.painting.PaintingEngineType;
import org.dromara.ai.painting.PaintingTask;
import org.dromara.ai.service.AiPaintingService;
import org.dromara.common.core.domain.R;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.util.Map;

/**
 * AI绘画控制器
 * 提供统一的AI绘画任务管理和状态查询接口
 *
 * @author pengles
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/ai/painting")
public class AiPaintingController {
    
    private final AiPaintingService paintingService;

    /**
     * 创建绘画任务
     *
     * @param body 请求体，包含engine（引擎类型）、prompt（提示词）、params（参数）
     * @return 任务ID
     */
    @Operation(summary = "创建绘画任务", description = "创建一个新的AI绘画任务，支持多种绘画引擎")
    @PostMapping("/task")
    public R<Map<String, Object>> createTask(@RequestBody Map<String, Object> body) {
        try {
            String engine = String.valueOf(body.getOrDefault("engine", "DALL_E_3"));
            String prompt = String.valueOf(body.getOrDefault("prompt", ""));
            Map<String, Object> params = (Map<String, Object>) body.getOrDefault("params", Map.of());
            
            log.info("创建绘画任务 - 引擎: {}, 提示词长度: {}", engine, prompt.length());
            
            PaintingEngineType type = PaintingEngineType.valueOf(engine);
            String taskId = paintingService.createTask(type, prompt, params);
            
            log.info("绘画任务创建成功 - 任务ID: {}", taskId);
            return R.ok(Map.of("taskId", taskId));
        } catch (IllegalArgumentException e) {
            log.error("创建绘画任务失败 - 无效的引擎类型", e);
            return R.fail("无效的引擎类型: " + e.getMessage());
        } catch (Exception e) {
            log.error("创建绘画任务失败", e);
            return R.fail("创建任务失败: " + e.getMessage());
        }
    }

    /**
     * 查询任务状态
     *
     * @param taskId 任务ID
     * @return 任务状态信息
     */
    @Operation(summary = "任务状态", description = "查询指定绘画任务的当前状态")
    @GetMapping("/status/{taskId}")
    public R<PaintingTask> status(
            @Parameter(description = "任务ID", required = true)
            @PathVariable("taskId") String taskId) {
        try {
            log.debug("查询绘画任务状态 - 任务ID: {}", taskId);
            PaintingTask task = paintingService.getTask(taskId);
            if (task == null) {
                log.warn("绘画任务不存在 - 任务ID: {}", taskId);
                return R.fail("TASK_NOT_FOUND");
            }
            return R.ok(task);
        } catch (Exception e) {
            log.error("查询绘画任务状态失败 - 任务ID: {}", taskId, e);
            return R.fail("查询任务状态失败: " + e.getMessage());
        }
    }

    /**
     * 任务进度流（SSE）
     *
     * @param taskId 任务ID
     * @return SSE事件流
     */
    @Operation(summary = "进度流", description = "通过SSE实时获取绘画任务的进度更新")
    @GetMapping(value = "/stream/{taskId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter stream(
            @Parameter(description = "任务ID", required = true)
            @PathVariable("taskId") String taskId) {
        try {
            log.info("创建绘画任务进度流 - 任务ID: {}", taskId);
            SseEmitter emitter = new SseEmitter(0L);
            paintingService.addEmitter(taskId, emitter);
            return emitter;
        } catch (Exception e) {
            log.error("创建绘画任务进度流失败 - 任务ID: {}", taskId, e);
            SseEmitter emitter = new SseEmitter(0L);
            try {
                emitter.send(SseEmitter.event().name("error").data("创建进度流失败: " + e.getMessage()));
                emitter.completeWithError(e);
            } catch (Exception ex) {
                log.error("发送错误事件失败", ex);
            }
            return emitter;
        }
    }
}

