import { describe, expect, it } from "vitest";
import {
  ASSISTANT_CONFIRMATION_PREFIX,
  buildApprovalSummary,
  canExecuteMutationTool,
  formatApprovalValue,
  isAffirmativeConfirmationReply,
  isCancellationReply,
  parseToolArguments,
} from "../router/assistant-confirmation.js";

describe("assistant confirmation", () => {
  it("parses tool arguments defensively", () => {
    expect(parseToolArguments("{\"name\":\"Apollo\",\"status\":\"DRAFT\"}")).toEqual({
      name: "Apollo",
      status: "DRAFT",
    });
    expect(parseToolArguments("[]")).toEqual({});
    expect(parseToolArguments("not-json")).toEqual({});
  });

  it("formats approval values compactly", () => {
    expect(formatApprovalValue("Apollo")).toBe("Apollo");
    expect(formatApprovalValue("x".repeat(60))).toBe(`${"x".repeat(45)}...`);
    expect(formatApprovalValue([1, "two", true, "four"])).toBe("[1, two, true, ...]");
    expect(formatApprovalValue({ nested: true })).toBe("{...}");
  });

  it("builds compact approval summaries from tool calls", () => {
    expect(buildApprovalSummary(
      "create_project",
      JSON.stringify({ name: "Apollo", status: "DRAFT", budgetCents: 1200000 }),
    )).toBe("create project (name=Apollo, status=DRAFT, budgetCents=1200000)");
    expect(buildApprovalSummary("delete_project", "{}")).toBe("delete project");
  });

  it("recognizes affirmative and cancellation replies in multiple phrasings", () => {
    expect(isAffirmativeConfirmationReply("ja, bitte ausführen")).toBe(true);
    expect(isAffirmativeConfirmationReply("go ahead")).toBe(true);
    expect(isAffirmativeConfirmationReply("vielleicht")).toBe(false);

    expect(isCancellationReply("nein, abbrechen")).toBe(true);
    expect(isCancellationReply("stop")).toBe(true);
    expect(isCancellationReply("später")).toBe(false);
  });

  it("blocks mutation tools until the user confirms a prior assistant summary", () => {
    expect(canExecuteMutationTool([
      { role: "user", content: "Lege bitte ein Projekt an" },
    ], "create_project")).toBe(false);

    expect(canExecuteMutationTool([
      { role: "user", content: "Lege bitte ein Projekt an" },
      { role: "assistant", content: "Ich werde jetzt das Projekt erstellen." },
      { role: "user", content: "ja" },
    ], "create_project")).toBe(false);

    expect(canExecuteMutationTool([
      { role: "user", content: "Lege bitte ein Projekt an" },
      { role: "assistant", content: `${ASSISTANT_CONFIRMATION_PREFIX} Ich werde das Projekt \"Apollo\" in DRAFT anlegen. Bitte bestätigen.` },
      { role: "user", content: "ja, bitte ausführen" },
    ], "create_project")).toBe(true);
  });

  it("requires a matching server-side pending approval for mutation execution when provided", () => {
    const pendingApproval = {
      id: "approval-1",
      userId: "user-1",
      conversationId: "conversation-1",
      toolName: "create_project",
      toolArguments: JSON.stringify({ name: "Apollo", status: "DRAFT" }),
      summary: "create project (name=Apollo, status=DRAFT)",
      createdAt: Date.now(),
      expiresAt: Date.now() + 60_000,
    };

    expect(canExecuteMutationTool([
      { role: "assistant", content: `${ASSISTANT_CONFIRMATION_PREFIX} create project (name=Apollo). Bitte bestätigen.` },
      { role: "user", content: "ja" },
    ], "create_project", pendingApproval)).toBe(true);

    expect(canExecuteMutationTool([
      { role: "assistant", content: `${ASSISTANT_CONFIRMATION_PREFIX} create project (name=Apollo). Bitte bestätigen.` },
      { role: "user", content: "ja" },
    ], "delete_project", pendingApproval)).toBe(false);
  });

  it("does not require confirmation for read-only assistant tools", () => {
    expect(canExecuteMutationTool([
      { role: "user", content: "Zeig mir meine Notifications" },
    ], "list_notifications")).toBe(true);
  });
});
