import { describe, it, expect, vi, beforeEach } from "vitest";
import { classifyMessage } from "./classifier.js";
import type { ComplaintHistoryEntry } from "./types.js";

vi.mock("../../../src/agents/llm-tools/forced-tool-call.js", () => ({
  forcedToolCall: vi.fn(),
}));

import { forcedToolCall } from "../../../src/agents/llm-tools/forced-tool-call.js";

describe("classifyMessage with history", () => {
  beforeEach(() => vi.resetAllMocks());

  const history: ComplaintHistoryEntry[] = [
    { role: "user", content: "hi", ts: 1 },
    { role: "agent", content: "hello, how can I help?", ts: 2 },
    { role: "user", content: "your product is broken", ts: 3 },
  ];

  it("invokes forcedToolCall with history rendered in prompt", async () => {
    (forcedToolCall as any).mockResolvedValue({
      is_complaint: true,
      severity: "high",
      category: "product_defect",
      summary: "Broken product",
    });
    await classifyMessage(history, "k", "claude-haiku-4-5");
    const args = (forcedToolCall as any).mock.calls[0];
    expect(args[0]).toContain("hi");
    expect(args[0]).toContain("hello, how can I help?");
    expect(args[0]).toContain("your product is broken");
  });

  it("returns the parsed complaint result", async () => {
    (forcedToolCall as any).mockResolvedValue({
      is_complaint: true,
      severity: "high",
      category: "billing",
      summary: "Billing dispute",
    });
    const result = await classifyMessage(history, "k", "claude-haiku-4-5");
    expect(result.is_complaint).toBe(true);
    expect(result.category).toBe("billing");
  });

  it("handles non-complaint result", async () => {
    (forcedToolCall as any).mockResolvedValue({
      is_complaint: false,
      severity: "low",
      category: "other",
      summary: "",
    });
    const result = await classifyMessage(history, "k", "claude-haiku-4-5");
    expect(result.is_complaint).toBe(false);
  });

  it("passes signal through", async () => {
    (forcedToolCall as any).mockResolvedValue({ is_complaint: false, severity: "low", category: "other", summary: "" });
    const controller = new AbortController();
    await classifyMessage(history, "k", "claude-haiku-4-5", controller.signal);
    expect((forcedToolCall as any).mock.calls[0][2]?.signal).toBe(controller.signal);
  });
});
