package com.sino.mci.inbound.intent;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.model.Generation;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.web.client.RestClient;

import java.util.List;
import java.util.Map;

/**
 * 基于 {@code RestClient} 的 OpenAI ChatModel 最小实现。
 *
 * <p>Spring AI 1.0.0-M6 的 {@code OpenAiChatModel} 与当前 Spring Boot 4.1 / Spring Framework 7
 * 存在二进制不兼容（{@code HttpHeaders.addAll} 返回类型变化），因此使用该实现替代，
 * 仍通过 Spring AI {@link ChatModel} 接入 {@code ChatClient}。</p>
 */
@Slf4j
public class OpenAiRestChatModel implements ChatModel {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    private final String baseUrl;
    private final String apiKey;
    private final String model;
    private final RestClient restClient;

    public OpenAiRestChatModel(String baseUrl, String apiKey, String model) {
        this.baseUrl = baseUrl.endsWith("/") ? baseUrl.substring(0, baseUrl.length() - 1) : baseUrl;
        this.apiKey = apiKey;
        this.model = model;
        this.restClient = RestClient.builder()
                .baseUrl(this.baseUrl)
                .defaultHeader("Authorization", "Bearer " + apiKey)
                .build();
    }

    @Override
    public ChatResponse call(Prompt prompt) {
        String text = prompt.getContents();
        Map<String, Object> request = Map.of(
                "model", model,
                "messages", List.of(Map.of("role", "user", "content", text)));

        try {
            String responseBody = restClient.post()
                    .uri("/v1/chat/completions")
                    .body(request)
                    .retrieve()
                    .body(String.class);
            String content = extractContent(responseBody);
            return new ChatResponse(List.of(new Generation(new AssistantMessage(content))));
        } catch (Exception e) {
            log.warn("OpenAI REST call failed: {}", e.getMessage());
            throw new RuntimeException("LLM call failed", e);
        }
    }

    @SuppressWarnings("unchecked")
    private String extractContent(String responseBody) {
        if (responseBody == null || responseBody.isBlank()) {
            return "";
        }
        try {
            Map<String, Object> root = OBJECT_MAPPER.readValue(responseBody, Map.class);
            Object choices = root.get("choices");
            if (!(choices instanceof List<?> list) || list.isEmpty()) {
                return "";
            }
            Object first = list.get(0);
            if (!(first instanceof Map<?, ?> choice)) {
                return "";
            }
            Object message = choice.get("message");
            if (!(message instanceof Map<?, ?> msg)) {
                return "";
            }
            Object content = msg.get("content");
            return content != null ? content.toString() : "";
        } catch (Exception e) {
            log.warn("Failed to parse LLM response: {}", e.getMessage());
            return "";
        }
    }
}
