package tech.easyflow.ai.entity;

import com.easyagents.core.message.AiMessage;
import com.easyagents.core.message.Message;
import com.easyagents.core.message.ToolMessage;
import com.easyagents.core.model.client.OpenAIChatMessageSerializer;
import com.easyagents.llm.deepseek.DeepseekConfig;
import org.junit.Assert;
import org.junit.Test;
import tech.easyflow.ai.easyagents.memory.PublicBotMessageMemory;
import tech.easyflow.core.chat.protocol.sse.ChatSseEmitter;

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

/**
 * {@link ChatRequestParams} 测试。
 */
public class ChatRequestParamsTest {

    /**
     * 应兼容解析 assistant 的 reasoning 与 OpenAI 风格 tool_calls。
     */
    @Test
    public void shouldParseAssistantReasoningAndToolCalls() {
        ChatRequestParams params = new ChatRequestParams();
        params.setMessagesFromJson(List.of(
                Map.of(
                        "role", "assistant",
                        "content", "",
                        "reasoning_content", "先思考",
                        "tool_calls", List.of(
                                Map.of(
                                        "id", "call-1",
                                        "type", "function",
                                        "function", Map.of(
                                                "name", "kb_search",
                                                "arguments", "{\"query\":\"test\"}"
                                        )
                                )
                        )
                )
        ));

        Message message = params.getMessages().get(0);
        Assert.assertTrue(message instanceof AiMessage);
        AiMessage aiMessage = (AiMessage) message;
        Assert.assertEquals("先思考", aiMessage.getReasoningContent());
        Assert.assertEquals(1, aiMessage.getToolCalls().size());
        Assert.assertEquals("kb_search", aiMessage.getToolCalls().get(0).getName());
        Assert.assertEquals("{\"query\":\"test\"}", aiMessage.getToolCalls().get(0).getArguments());
    }

    /**
     * 应兼容解析 tool 消息的下划线字段。
     */
    @Test
    public void shouldParseToolMessageWithSnakeCaseToolCallId() {
        ChatRequestParams params = new ChatRequestParams();
        params.setMessagesFromJson(List.of(
                Map.of(
                        "role", "tool",
                        "content", "{\"hits\":1}",
                        "tool_call_id", "call-2"
                )
        ));

        Message message = params.getMessages().get(0);
        Assert.assertTrue(message instanceof ToolMessage);
        ToolMessage toolMessage = (ToolMessage) message;
        Assert.assertEquals("call-2", toolMessage.getToolCallId());
        Assert.assertEquals("{\"hits\":1}", toolMessage.getContent());
    }

    /**
     * public-api 多轮 assistant/tool 历史透传后，DeepSeek 后续轮次序列化不应丢字段。
     */
    @Test
    public void shouldKeepPublicApiAssistantAndToolHistoryForDeepseekFollowUp() {
        ChatRequestParams params = new ChatRequestParams();
        params.setMessagesFromJson(List.of(
                Map.of(
                        "role", "assistant",
                        "content", "",
                        "reasoning_content", "先思考",
                        "tool_calls", List.of(
                                Map.of(
                                        "id", "call-1",
                                        "type", "function",
                                        "function", Map.of(
                                                "name", "kb_search",
                                                "arguments", "{\"query\":\"test\"}"
                                        )
                                )
                        )
                ),
                Map.of(
                        "role", "tool",
                        "content", "{\"hits\":1}",
                        "tool_call_id", "call-1"
                )
        ));

        PublicBotMessageMemory memory = new PublicBotMessageMemory(new ChatSseEmitter(), params.getMessages());
        DeepseekConfig config = new DeepseekConfig();
        config.setSupportThinking(Boolean.TRUE);
        config.setThinkingProtocol("deepseek");
        config.setNeedReasoningContentForToolMessage(Boolean.TRUE);

        List<Map<String, Object>> serialized = new OpenAIChatMessageSerializer()
                .serializeMessages(memory.getMessages(10), config);

        Assert.assertEquals(2, serialized.size());
        Assert.assertEquals("assistant", serialized.get(0).get("role"));
        Assert.assertEquals("先思考", serialized.get(0).get("reasoning_content"));
        Assert.assertTrue(serialized.get(0).containsKey("tool_calls"));
        Assert.assertEquals("tool", serialized.get(1).get("role"));
        Assert.assertEquals("call-1", serialized.get(1).get("tool_call_id"));
    }
}
