import { describe, it, expect, afterEach } from "vitest";
import { get } from "svelte/store";
import {
  claudeStore,
  hasPermissionPending,
  hasQuestionPending,
  isClaudeProcessing,
} from "./claude";
import { conversationsStore } from "./conversations";
import { characterState } from "$lib/stores/character";
import type { PermissionRequest, UserQuestionEvent } from "$lib/types/messages";

describe("claudeStore (compatibility wrapper)", () => {
  afterEach(() => {
    conversationsStore.revokeAllTools();
    conversationsStore.clearPermission();
    conversationsStore.clearQuestion();
    conversationsStore.setConnectionStatus("disconnected");
    characterState.setState("idle");
  });

  describe("getGrantedTools", () => {
    it("returns an empty array when no tools are granted", () => {
      expect(claudeStore.getGrantedTools()).toEqual([]);
    });

    it("returns granted tools as an array", () => {
      conversationsStore.grantTool("Read");
      conversationsStore.grantTool("Write");

      const tools = claudeStore.getGrantedTools();

      expect(tools).toContain("Read");
      expect(tools).toContain("Write");
    });
  });

  describe("reset", () => {
    it("clears terminal lines and resets processing state", () => {
      conversationsStore.setProcessing(true);
      conversationsStore.grantTool("Edit");

      claudeStore.reset();

      expect(get(conversationsStore.isProcessing)).toBe(false);
      expect(claudeStore.getGrantedTools()).toEqual([]);
    });
  });
});

describe("hasPermissionPending derived store", () => {
  afterEach(() => {
    conversationsStore.clearPermission();
  });

  it("is false when there are no pending permissions", () => {
    expect(get(hasPermissionPending)).toBe(false);
  });

  it("is true when there is a pending permission request", () => {
    const request: PermissionRequest = {
      id: "perm-1",
      tool: "Bash",
      description: "Run a shell command",
      input: { command: "ls" },
    };

    conversationsStore.requestPermission(request);

    expect(get(hasPermissionPending)).toBe(true);

    conversationsStore.clearPermission();
  });
});

describe("hasQuestionPending derived store", () => {
  afterEach(() => {
    conversationsStore.clearQuestion();
  });

  it("is false when there is no pending question", () => {
    expect(get(hasQuestionPending)).toBe(false);
  });

  it("is true when there is a pending question", () => {
    const question: UserQuestionEvent = {
      id: "q-1",
      question: "Which approach do you prefer?",
      options: [{ label: "A" }, { label: "B" }],
      multi_select: false,
    };

    conversationsStore.requestQuestion(question);

    expect(get(hasQuestionPending)).toBe(true);
  });
});

describe("isClaudeProcessing derived store", () => {
  afterEach(() => {
    conversationsStore.setConnectionStatus("disconnected");
    characterState.setState("idle");
  });

  it("is false when disconnected regardless of character state", () => {
    conversationsStore.setConnectionStatus("disconnected");
    characterState.setState("thinking");

    expect(get(isClaudeProcessing)).toBe(false);
  });

  it("is false when connected but in idle state", () => {
    conversationsStore.setConnectionStatus("connected");
    characterState.setState("idle");

    expect(get(isClaudeProcessing)).toBe(false);
  });

  it("is true when connected and in thinking state", () => {
    conversationsStore.setConnectionStatus("connected");
    characterState.setState("thinking");

    expect(get(isClaudeProcessing)).toBe(true);
  });

  it("is true when connected and in coding state", () => {
    conversationsStore.setConnectionStatus("connected");
    characterState.setState("coding");

    expect(get(isClaudeProcessing)).toBe(true);
  });

  it("is true when connected and in searching state", () => {
    conversationsStore.setConnectionStatus("connected");
    characterState.setState("searching");

    expect(get(isClaudeProcessing)).toBe(true);
  });
});
