import {
  parseAssistantMessageSections,
  parseContentWithToolCalls,
} from "./chatMessageSections";

describe("parseAssistantMessageSections", () => {
  it("returns plain assistant content when there is no thought block", () => {
    expect(parseAssistantMessageSections("直接回答")).toEqual({
      answer: "直接回答",
      thought: null,
      thoughtComplete: false,
    });
  });

  it("extracts a completed thought block and keeps the final answer visible", () => {
    expect(
      parseAssistantMessageSections("<think>先分析需求</think>\n\n最终回答"),
    ).toEqual({
      answer: "最终回答",
      thought: "先分析需求",
      thoughtComplete: true,
    });
  });

  it("supports streaming thought content before the closing tag arrives", () => {
    expect(
      parseAssistantMessageSections("准备中...\n<think>继续推理中"),
    ).toEqual({
      answer: "准备中...",
      thought: "继续推理中",
      thoughtComplete: false,
    });
  });

  it("merges multiple thought blocks into a single collapsed section", () => {
    expect(
      parseAssistantMessageSections(
        "<think>第一段思考</think>\n答案开头\n<think>第二段思考</think>\n答案结尾",
      ),
    ).toEqual({
      answer: "答案开头\n\n答案结尾",
      thought: "第一段思考\n\n第二段思考",
      thoughtComplete: true,
    });
  });
});

describe("parseContentWithToolCalls", () => {
  it("returns a single text segment when there are no tool calls", () => {
    const result = parseContentWithToolCalls("普通文本回答");
    expect(result.segments).toEqual([
      { type: "text", content: "普通文本回答" },
    ]);
    expect(result.toolCalls).toHaveLength(0);
  });

  it("parses a complete tool_call block", () => {
    const content =
      '分析完成。\n<tool_call>{"tool":"locate_junctions","params":{"ids":["J1","J2"]}}</tool_call>\n以上是结果。';
    const result = parseContentWithToolCalls(content);

    expect(result.toolCalls).toHaveLength(1);
    expect(result.toolCalls[0].tool).toBe("locate_junctions");
    expect(result.toolCalls[0].params).toEqual({ ids: ["J1", "J2"] });

    expect(result.segments).toHaveLength(3);
    expect(result.segments[0]).toEqual({
      type: "text",
      content: "分析完成。",
    });
    expect(result.segments[1]).toMatchObject({
      type: "tool_call",
      toolCall: { tool: "locate_junctions" },
    });
    expect(result.segments[2]).toEqual({
      type: "text",
      content: "以上是结果。",
    });
  });

  it("parses multiple tool_call blocks", () => {
    const content =
      '文本1\n<tool_call>{"tool":"locate_pipes","params":{"ids":["P1"]}}</tool_call>\n文本2\n<tool_call>{"tool":"chart","params":{"title":"图"}}</tool_call>';
    const result = parseContentWithToolCalls(content);

    expect(result.toolCalls).toHaveLength(2);
    expect(result.toolCalls[0].tool).toBe("locate_pipes");
    expect(result.toolCalls[1].tool).toBe("chart");
    expect(result.segments).toHaveLength(4);
  });

  it("detects an unclosed tool_call tag as pending (streaming)", () => {
    const content = '正在分析...\n<tool_call>{"tool":"locate_no';
    const result = parseContentWithToolCalls(content);

    expect(result.segments).toHaveLength(2);
    expect(result.segments[0]).toEqual({
      type: "text",
      content: "正在分析...",
    });
    expect(result.segments[1]).toEqual({ type: "tool_call_pending" });
    expect(result.toolCalls).toHaveLength(0);
  });

  it("strips partial opening tags during streaming", () => {
    const content = "正在分析...\n<tool_c";
    const result = parseContentWithToolCalls(content);

    expect(result.segments).toHaveLength(1);
    expect(result.segments[0]).toEqual({
      type: "text",
      content: "正在分析...",
    });
  });

  it("handles malformed JSON gracefully", () => {
    const content =
      '前文\n<tool_call>{invalid json}</tool_call>\n后文';
    const result = parseContentWithToolCalls(content);

    // Malformed tool call is treated as text
    expect(result.toolCalls).toHaveLength(0);
    expect(result.segments.length).toBeGreaterThanOrEqual(2);
  });

  it("returns empty segments for empty content", () => {
    const result = parseContentWithToolCalls("");
    expect(result.segments).toHaveLength(0);
    expect(result.toolCalls).toHaveLength(0);
  });
});
