package org.dromara.ai.controller.app;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.tika.Tika;
import org.dromara.common.core.domain.R;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 多模态控制器
 * 提供文件解析、OCR识别、图像识别、图生文等功能
 *
 * @author pengles
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/multimodal")
public class MultimodalController {

    @Value("${ruoyi.ai.ocr.base-url:}")
    private String ocrBaseUrl;

    @Value("${ruoyi.ai.external-ai.openai.api-key:}")
    private String openaiApiKey;

    @Value("${ruoyi.ai.external-ai.openai.base-url:https://api.openai.com}")
    private String openaiBaseUrl;

    @Operation(summary = "文件解析")
    @PostMapping(value = "/extract", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R<Map<String, Object>> extract(
            @Parameter(description = "文件") @RequestParam("file") @NotNull MultipartFile file) {
        try {
            Tika tika = new Tika();
            String text = tika.parseToString(file.getInputStream());
            String summary = summarize(text);
            return R.ok(Map.of("text", text, "summary", summary));
        } catch (Exception e) {
            log.error("文件解析失败", e);
            return R.fail("解析失败: " + e.getMessage());
        }
    }

    @Operation(summary = "OCR识别")
    @PostMapping(value = "/ocr", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<byte[]> ocr(
            @Parameter(description = "图片") @RequestParam("file") @NotNull MultipartFile file) {
        try {
            if (ocrBaseUrl == null || ocrBaseUrl.isBlank()) {
                String msg = "{\"code\":500,\"msg\":\"OCR未配置\",\"data\":null}";
                return ResponseEntity.status(500).contentType(MediaType.APPLICATION_JSON)
                        .body(msg.getBytes(StandardCharsets.UTF_8));
            }
            // TODO: 实现OCR服务调用
            String msg = "{\"code\":200,\"msg\":\"OK\",\"data\":{\"text\":\"\"}}";
            return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON)
                    .body(msg.getBytes(StandardCharsets.UTF_8));
        } catch (Exception e) {
            log.error("OCR识别失败", e);
            String msg = "{\"code\":500,\"msg\":\"" + e.getMessage().replace("\"", "\\\"") + "\",\"data\":null}";
            return ResponseEntity.status(500).contentType(MediaType.APPLICATION_JSON)
                    .body(msg.getBytes(StandardCharsets.UTF_8));
        }
    }

    @Operation(summary = "文本分析")
    @PostMapping("/analyze/text")
    public R<Map<String, Object>> analyzeText(
            @Parameter(description = "文本") @RequestParam("text") String text) {
        try {
            String t = text == null ? "" : text.trim();
            String summary = summarize(t);
            List<String> keywords = Arrays.stream(t.split("\\s+"))
                    .filter(s -> s.length() > 3)
                    .limit(10)
                    .collect(Collectors.toList());
            String title = t.length() > 16 ? t.substring(0, 16) : t;
            return R.ok(Map.of("title", title, "summary", summary, "keywords", keywords));
        } catch (Exception e) {
            log.error("文本分析失败", e);
            return R.fail("文本分析失败: " + e.getMessage());
        }
    }

    @Operation(summary = "图像识别", description = "使用AI模型识别图像内容，返回标签和描述")
    @PostMapping(value = "/analyze/image", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R<Map<String, Object>> analyzeImage(
            @Parameter(description = "图片") @RequestParam("file") @NotNull MultipartFile file,
            @Parameter(description = "模型名称") @RequestParam(required = false) String model) {
        try {
            // 检查是否配置了OpenAI API Key
            if (openaiApiKey == null || openaiApiKey.isBlank()) {
                return R.ok(Map.of("labels", List.of(), "description", "",
                        "msg", "VISION_PROVIDER_NOT_CONFIGURED",
                        "error", "OpenAI API Key未配置"));
            }

            // 由于当前 AiMessage.content 是 String 类型，Vision API 的多模态支持需要在 Provider 层面实现
            // 这里提供一个占位实现，提示用户使用支持 Vision 的模型
            // 实际使用时，需要在 OpenAiProvider 中扩展支持多模态消息格式
            
            log.warn("图像识别功能需要 Vision API 支持，当前实现为占位，请使用支持 Vision 的模型（如 gpt-4-vision-preview）");
            
            return R.ok(Map.of("labels", List.of(), "description", "",
                    "msg", "VISION_API_NOT_FULLY_IMPLEMENTED",
                    "hint", "此功能需要 Vision API 支持。当前 AiMessage 接口限制，建议直接使用 OpenAI Vision API 或扩展 Provider 接口"));
        } catch (Exception e) {
            log.error("图像识别失败", e);
            return R.ok(Map.of("labels", List.of(), "description", "",
                    "msg", "VISION_ANALYSIS_ERROR",
                    "error", e.getMessage()));
        }
    }

    @Operation(summary = "图生文", description = "使用AI模型为图片生成描述文本")
    @PostMapping(value = "/caption", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R<Map<String, Object>> caption(
            @Parameter(description = "图片") @RequestParam("file") @NotNull MultipartFile file,
            @Parameter(description = "模型名称") @RequestParam(required = false) String model) {
        try {
            // 检查是否配置了OpenAI API Key
            if (openaiApiKey == null || openaiApiKey.isBlank()) {
                return R.ok(Map.of("text", "", "msg", "CAPTION_PROVIDER_NOT_CONFIGURED",
                        "error", "OpenAI API Key未配置"));
            }

            // 由于当前 AiMessage.content 是 String 类型，Vision API 的多模态支持需要在 Provider 层面实现
            // 这里提供一个占位实现，提示用户使用支持 Vision 的模型
            
            log.warn("图生文功能需要 Vision API 支持，当前实现为占位，请使用支持 Vision 的模型（如 gpt-4-vision-preview）");
            
            return R.ok(Map.of("text", "", "msg", "CAPTION_API_NOT_FULLY_IMPLEMENTED",
                    "hint", "此功能需要 Vision API 支持。当前 AiMessage 接口限制，建议直接使用 OpenAI Vision API 或扩展 Provider 接口"));
        } catch (Exception e) {
            log.error("图生文失败", e);
            return R.ok(Map.of("text", "", "msg", "CAPTION_GENERATION_ERROR",
                    "error", e.getMessage()));
        }
    }


    /**
     * 文本摘要
     */
    private String summarize(String text) {
        if (text == null) return "";
        String s = text.trim().replaceAll("\\s+", " ");
        if (s.length() <= 200) return s;
        return s.substring(0, 200);
    }
}
