package com.emotion.service;

import com.emotion.entity.AiConfig;
import com.emotion.service.impl.AiChatServiceImpl;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

import java.lang.reflect.Method;

import static org.junit.jupiter.api.Assertions.*;

/**
 * AI聊天服务测试类
 * 测试apiBaseUrl字段调整后的接口调用逻辑
 * 
 * @author system
 * @date 2025-12-22
 */
@SpringBootTest
@ActiveProfiles("local")
public class AiChatServiceImplTest {

    private AiChatServiceImpl aiChatService;

    @BeforeEach
    public void setUp() {
        aiChatService = new AiChatServiceImpl();
    }

    @Test
    @DisplayName("测试getApiPath方法返回空字符串")
    public void testGetApiPath() throws Exception {
        // 使用反射调用私有方法
        Method getApiPathMethod = AiChatServiceImpl.class.getDeclaredMethod("getApiPath", AiConfig.class);
        getApiPathMethod.setAccessible(true);

        AiConfig config = AiConfig.builder()
                .apiBaseUrl("https://api.coze.cn/v3/chat")
                .build();

        String result = (String) getApiPathMethod.invoke(aiChatService, config);

        // 验证返回空字符串，因为apiBaseUrl已经是完整URL
        assertEquals("", result, "getApiPath应该返回空字符串");
    }

    @Test
    @DisplayName("测试extractBaseUrl方法提取基础URL")
    public void testExtractBaseUrl() throws Exception {
        // 使用反射调用私有方法
        Method extractBaseUrlMethod = AiChatServiceImpl.class.getDeclaredMethod("extractBaseUrl", String.class);
        extractBaseUrlMethod.setAccessible(true);

        // 测试标准URL
        String apiBaseUrl1 = "https://api.coze.cn/v3/chat";
        String result1 = (String) extractBaseUrlMethod.invoke(aiChatService, apiBaseUrl1);
        assertEquals("https://api.coze.cn", result1, "应该正确提取基础URL");

        // 测试带端口的URL
        String apiBaseUrl2 = "http://localhost:8080/v3/chat";
        String result2 = (String) extractBaseUrlMethod.invoke(aiChatService, apiBaseUrl2);
        assertEquals("http://localhost:8080", result2, "应该正确提取带端口的基础URL");

        // 测试只有域名的URL
        String apiBaseUrl3 = "https://api.example.com";
        String result3 = (String) extractBaseUrlMethod.invoke(aiChatService, apiBaseUrl3);
        assertEquals("https://api.example.com", result3, "应该正确处理只有域名的URL");

        // 测试空字符串
        String apiBaseUrl4 = "";
        String result4 = (String) extractBaseUrlMethod.invoke(aiChatService, apiBaseUrl4);
        assertEquals("", result4, "空字符串应该返回空字符串");

        // 测试null
        String result5 = (String) extractBaseUrlMethod.invoke(aiChatService, (String) null);
        assertEquals("", result5, "null应该返回空字符串");
    }

    @Test
    @DisplayName("测试完整API URL的构建逻辑")
    public void testApiUrlConstruction() throws Exception {
        Method getApiPathMethod = AiChatServiceImpl.class.getDeclaredMethod("getApiPath", AiConfig.class);
        getApiPathMethod.setAccessible(true);

        // 创建配置对象，apiBaseUrl是完整的API URL
        AiConfig config = AiConfig.builder()
                .apiBaseUrl("https://api.coze.cn/v3/chat")
                .apiToken("test_token")
                .botId("test_bot_id")
                .build();

        String apiPath = (String) getApiPathMethod.invoke(aiChatService, config);

        // 模拟实际调用时的URL构建
        String fullUrl = config.getApiBaseUrl() + apiPath;

        // 验证完整URL就是apiBaseUrl本身
        assertEquals("https://api.coze.cn/v3/chat", fullUrl, 
                "完整URL应该等于apiBaseUrl，因为apiPath为空");
    }

    @Test
    @DisplayName("测试状态查询URL的构建逻辑")
    public void testStatusQueryUrlConstruction() throws Exception {
        Method extractBaseUrlMethod = AiChatServiceImpl.class.getDeclaredMethod("extractBaseUrl", String.class);
        extractBaseUrlMethod.setAccessible(true);

        // 创建配置对象
        AiConfig config = AiConfig.builder()
                .apiBaseUrl("https://api.coze.cn/v3/chat")
                .build();

        String baseUrl = (String) extractBaseUrlMethod.invoke(aiChatService, config.getApiBaseUrl());
        String chatId = "test_chat_id";
        String conversationId = "test_conversation_id";

        // 模拟状态查询URL构建
        String statusUrl = baseUrl + "/v3/chat/retrieve?chat_id=" + chatId + "&conversation_id=" + conversationId;

        // 验证状态查询URL格式正确
        assertEquals("https://api.coze.cn/v3/chat/retrieve?chat_id=test_chat_id&conversation_id=test_conversation_id", 
                statusUrl, "状态查询URL应该正确构建");
    }

    @Test
    @DisplayName("测试消息查询URL的构建逻辑")
    public void testMessageQueryUrlConstruction() throws Exception {
        Method extractBaseUrlMethod = AiChatServiceImpl.class.getDeclaredMethod("extractBaseUrl", String.class);
        extractBaseUrlMethod.setAccessible(true);

        // 创建配置对象
        AiConfig config = AiConfig.builder()
                .apiBaseUrl("https://api.coze.cn/v3/chat")
                .build();

        String baseUrl = (String) extractBaseUrlMethod.invoke(aiChatService, config.getApiBaseUrl());
        String chatId = "test_chat_id";
        String conversationId = "test_conversation_id";

        // 模拟消息查询URL构建
        String messagesUrl = baseUrl + "/v3/chat/message/list?chat_id=" + chatId + "&conversation_id=" + conversationId;

        // 验证消息查询URL格式正确
        assertEquals("https://api.coze.cn/v3/chat/message/list?chat_id=test_chat_id&conversation_id=test_conversation_id", 
                messagesUrl, "消息查询URL应该正确构建");
    }

    @Test
    @DisplayName("测试不同格式的apiBaseUrl")
    public void testDifferentApiBaseUrlFormats() throws Exception {
        Method getApiPathMethod = AiChatServiceImpl.class.getDeclaredMethod("getApiPath", AiConfig.class);
        Method extractBaseUrlMethod = AiChatServiceImpl.class.getDeclaredMethod("extractBaseUrl", String.class);
        getApiPathMethod.setAccessible(true);
        extractBaseUrlMethod.setAccessible(true);

        // 测试场景1：标准Coze API URL
        AiConfig config1 = AiConfig.builder()
                .apiBaseUrl("https://api.coze.cn/v3/chat")
                .build();
        String apiPath1 = (String) getApiPathMethod.invoke(aiChatService, config1);
        String fullUrl1 = config1.getApiBaseUrl() + apiPath1;
        assertEquals("https://api.coze.cn/v3/chat", fullUrl1);

        // 测试场景2：自定义API URL
        AiConfig config2 = AiConfig.builder()
                .apiBaseUrl("https://custom-api.example.com/ai/chat")
                .build();
        String apiPath2 = (String) getApiPathMethod.invoke(aiChatService, config2);
        String fullUrl2 = config2.getApiBaseUrl() + apiPath2;
        assertEquals("https://custom-api.example.com/ai/chat", fullUrl2);

        // 测试场景3：本地开发环境URL
        AiConfig config3 = AiConfig.builder()
                .apiBaseUrl("http://localhost:8080/api/v1/chat")
                .build();
        String apiPath3 = (String) getApiPathMethod.invoke(aiChatService, config3);
        String fullUrl3 = config3.getApiBaseUrl() + apiPath3;
        assertEquals("http://localhost:8080/api/v1/chat", fullUrl3);

        // 验证extractBaseUrl对这些URL的处理
        String baseUrl1 = (String) extractBaseUrlMethod.invoke(aiChatService, config1.getApiBaseUrl());
        assertEquals("https://api.coze.cn", baseUrl1);

        String baseUrl2 = (String) extractBaseUrlMethod.invoke(aiChatService, config2.getApiBaseUrl());
        assertEquals("https://custom-api.example.com", baseUrl2);

        String baseUrl3 = (String) extractBaseUrlMethod.invoke(aiChatService, config3.getApiBaseUrl());
        assertEquals("http://localhost:8080", baseUrl3);
    }

    @Test
    @DisplayName("测试边界情况")
    public void testEdgeCases() throws Exception {
        Method extractBaseUrlMethod = AiChatServiceImpl.class.getDeclaredMethod("extractBaseUrl", String.class);
        extractBaseUrlMethod.setAccessible(true);

        // 测试只有协议和域名的URL
        String url1 = "https://api.coze.cn";
        String result1 = (String) extractBaseUrlMethod.invoke(aiChatService, url1);
        assertEquals("https://api.coze.cn", result1);

        // 测试带多级路径的URL
        String url2 = "https://api.coze.cn/v3/chat/stream";
        String result2 = (String) extractBaseUrlMethod.invoke(aiChatService, url2);
        assertEquals("https://api.coze.cn", result2);

        // 测试带查询参数的URL（虽然不应该出现在apiBaseUrl中）
        String url3 = "https://api.coze.cn/v3/chat?version=1";
        String result3 = (String) extractBaseUrlMethod.invoke(aiChatService, url3);
        assertEquals("https://api.coze.cn", result3);
    }
}
