import { beforeEach, describe, expect, it, vi } from "vitest";
import { SystemRole } from "@capakraken/shared";

vi.mock("@capakraken/application", async (importOriginal) => {
  const actual = await importOriginal<typeof import("@capakraken/application")>();
  return {
    ...actual,
    getDashboardBudgetForecast: vi.fn().mockResolvedValue([]),
    getDashboardPeakTimes: vi.fn().mockResolvedValue([]),
    listAssignmentBookings: vi.fn().mockResolvedValue([]),
  };
});

import { executeTool } from "../router/assistant-tools.js";
import { createToolContext } from "./assistant-tools-user-self-service-test-helpers.js";

describe("assistant user self-service favorite project tools", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("reads favorite project ids through the real user router path", async () => {
    const db = {
      user: {
        findUnique: vi.fn().mockResolvedValue({
          favoriteProjectIds: ["project_1", "project_2"],
        }),
      },
    };
    const ctx = createToolContext(db, SystemRole.ADMIN);

    const result = await executeTool("get_favorite_project_ids", "{}", ctx);

    expect(db.user.findUnique).toHaveBeenCalledWith({
      where: { id: "user_1" },
      select: { favoriteProjectIds: true },
    });
    expect(JSON.parse(result.content)).toEqual(["project_1", "project_2"]);
  });

  it("adds a project to favorites through the real user router path", async () => {
    const db = {
      user: {
        findUnique: vi.fn().mockResolvedValue({
          favoriteProjectIds: ["project_1"],
        }),
        update: vi.fn().mockResolvedValue({}),
      },
    };
    const ctx = createToolContext(db, SystemRole.ADMIN);

    const result = await executeTool(
      "toggle_favorite_project",
      JSON.stringify({ projectId: "project_2" }),
      ctx,
    );

    expect(db.user.update).toHaveBeenCalledWith({
      where: { id: "user_1" },
      data: { favoriteProjectIds: ["project_1", "project_2"] },
    });
    expect(JSON.parse(result.content)).toEqual({
      success: true,
      favoriteProjectIds: ["project_1", "project_2"],
      added: true,
      message: "Added project to favorites.",
    });
    expect(result.action).toEqual({
      type: "invalidate",
      scope: ["project"],
    });
  });

  it("removes a project from favorites through the real user router path", async () => {
    const db = {
      user: {
        findUnique: vi.fn().mockResolvedValue({
          favoriteProjectIds: ["project_1", "project_2"],
        }),
        update: vi.fn().mockResolvedValue({}),
      },
    };
    const ctx = createToolContext(db, SystemRole.ADMIN);

    const result = await executeTool(
      "toggle_favorite_project",
      JSON.stringify({ projectId: "project_2" }),
      ctx,
    );

    expect(db.user.update).toHaveBeenCalledWith({
      where: { id: "user_1" },
      data: { favoriteProjectIds: ["project_1"] },
    });
    expect(JSON.parse(result.content)).toEqual({
      success: true,
      favoriteProjectIds: ["project_1"],
      added: false,
      message: "Removed project from favorites.",
    });
    expect(result.action).toEqual({
      type: "invalidate",
      scope: ["project"],
    });
  });
});
