package com.emoon.tongue.service.impl;

import cn.hutool.json.JSONUtil;
import com.emoon.tongue.service.ILLMService;
import com.emoon.tongue.utils.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 大模型服务实现类
 *
 * @author destiny
 * @date 2025-12-21
 */
@Slf4j
@Service
@Primary
public class LLMServiceImpl implements ILLMService {

    @Value("${ai.llm.api-key:}")
    private String llmApiKey;

    @Value("${ai.llm.stream:false}")
    private boolean llmStream;

    @Value("${ai.llm.enable-thinking:false}")
    private boolean llmEnableThinking;

    /**
     * 内网自签名证书场景：跳过 HTTPS 证书/主机名校验（仅建议内网使用）
     */
    @Value("${ai.llm.insecure-ssl:false}")
    private boolean llmInsecureSsl;

    /**
     * 调用大模型API（参考MedicalRecordQc123Service配置）
     */
    @Override
    public String callLLM(String prompt, String llmUrl, String llmModel, Integer llmMaxTokens) {
        if (prompt == null || prompt.trim().isEmpty()) {
            throw new IllegalArgumentException("prompt不能为空");
        }

        log.info("LLMService开始调用，prompt长度: {}", prompt.length());

        try {
            // 添加随机延迟，避免并发过高（100-300ms）
            Thread.sleep(100 + (int) (Math.random() * 200));

            // 构建消息列表
            List<Map<String, String>> messages = new ArrayList<>();

            // 根据prompt内容动态设置system prompt
            String systemPrompt;
            if (prompt.contains("主诉内容") && prompt.contains("中医可以治疗")) {
                // 主诉校验场景
                systemPrompt = "你是一名中医专家，专门负责校验患者主诉是否是中医可以治疗的症状。请严格按照要求，只回答\"是\"或\"否\"，不要添加任何解释。";
            } else {
                // 通用AI助手场景
                systemPrompt = "你是一名专业的AI助手，请根据用户输入提供准确、有帮助的回答。";
            }

            messages.add(Map.of("role", "system", "content", systemPrompt));
            messages.add(Map.of("role", "user", "content", prompt));

            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("model", llmModel);
            // 注意：本项目后端按“非流式 JSON”解析，因此默认关闭 stream
            requestBody.put("stream", llmStream);
            requestBody.put("temperature", 0.0);
            requestBody.put("messages", messages);
            requestBody.put("max_tokens", llmMaxTokens);
            Map<String, Object> chatTemplateKwargs = new HashMap<>();
            chatTemplateKwargs.put("enable_thinking", llmEnableThinking);
            requestBody.put("chat_template_kwargs", chatTemplateKwargs);

            String jsonBody = JSONUtil.toJsonStr(requestBody);

            // 使用HttpUtils发送POST请求
            log.info("开始调用大模型API, URL: {}, 请求体长度: {}", llmUrl, jsonBody.length());
            Map<String, String> headers = new HashMap<>();
            if (llmApiKey != null && !llmApiKey.trim().isEmpty()) {
                headers.put("Authorization", "Bearer " + llmApiKey.trim());
            }
            String responseBody = HttpUtils.sendHttpPostByJson(
                llmUrl,
                jsonBody,
                headers.isEmpty() ? null : headers,
                llmInsecureSsl
            );
            log.info("大模型API调用完成，响应是否为null: {}, 响应内容: {}",
                     responseBody == null, responseBody != null ? responseBody.substring(0, Math.min(200, responseBody.length())) : "null");

            if (responseBody != null && !responseBody.trim().isEmpty()) {
                log.info("大模型API调用成功，响应长度: {}", responseBody.length());
                return responseBody;
            } else {
                log.error("API调用失败，响应为空或null。URL: {}, 请求体: {}", llmUrl, jsonBody);
                throw new RuntimeException("API调用失败，响应为空或null");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("调用被中断: " + e.getMessage());
        } catch (Exception e) {
            log.error("调用大模型API失败，URL: {}, 错误信息: {}", llmUrl, e.getMessage(), e);

            // 检查是否是网络连接问题
            if (e.getMessage() != null && e.getMessage().contains("Connection refused")) {
                throw new RuntimeException("无法连接到大模型API服务，请检查网络连接或API服务状态");
            } else if (e.getMessage() != null && e.getMessage().contains("timeout")) {
                throw new RuntimeException("大模型API调用超时，请稍后重试");
            } else {
                throw new RuntimeException("大模型API调用失败: " + e.getMessage());
            }
        }
    }

}
