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

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

import { countPlanningEntries } from "@capakraken/application";
import { executeTool } from "../router/assistant-tools.js";
import { createToolContext } from "./assistant-tools-master-data-read-test-helpers.js";

describe("assistant master data blueprint and rate-card read tools", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    vi.mocked(countPlanningEntries).mockResolvedValue({ countsByRoleId: new Map() });
  });

  it("routes blueprint and rate card reads through their backing routers", async () => {
    const db = {
      blueprint: {
        findMany: vi.fn().mockResolvedValue([
          {
            id: "bp_project",
            name: "Project Default",
            _count: { projects: 3 },
          },
        ]),
        findUnique: vi.fn().mockResolvedValue({
          id: "bp_project",
          name: "Project Default",
          fieldDefs: [{ key: "market", type: "text" }],
          rolePresets: [{ role: "Consulting", share: 0.5 }],
        }),
      },
      rateCard: {
        findMany: vi.fn().mockResolvedValue([
          {
            id: "rc_2026",
            name: "Standard 2026",
            effectiveFrom: new Date("2026-01-01T00:00:00.000Z"),
            effectiveTo: null,
            _count: { lines: 12 },
            client: null,
          },
        ]),
      },
    };
    const ctx = createToolContext(db, {
      userRole: SystemRole.ADMIN,
      permissions: [PermissionKey.VIEW_PLANNING, PermissionKey.VIEW_COSTS],
    });

    const blueprintsResult = await executeTool("list_blueprints", "{}", ctx);
    const blueprintResult = await executeTool(
      "get_blueprint",
      JSON.stringify({ identifier: "bp_project" }),
      ctx,
    );
    const rateCardsResult = await executeTool(
      "list_rate_cards",
      JSON.stringify({ query: "Standard", limit: 10 }),
      ctx,
    );

    expect(db.blueprint.findMany).toHaveBeenCalledWith({
      select: {
        id: true,
        name: true,
        _count: { select: { projects: true } },
      },
      orderBy: { name: "asc" },
    });
    expect(db.blueprint.findUnique).toHaveBeenCalledWith({
      where: { id: "bp_project" },
    });
    expect(db.rateCard.findMany).toHaveBeenCalledWith({
      where: {
        isActive: true,
        name: { contains: "Standard", mode: "insensitive" },
      },
      include: {
        _count: { select: { lines: true } },
        client: { select: { id: true, name: true, code: true } },
      },
      orderBy: [{ isActive: "desc" }, { effectiveFrom: "desc" }, { name: "asc" }],
    });

    expect(JSON.parse(blueprintsResult.content)).toEqual([
      {
        id: "bp_project",
        name: "Project Default",
        projectCount: 3,
      },
    ]);
    expect(JSON.parse(blueprintResult.content)).toEqual(
      expect.objectContaining({
        id: "bp_project",
        name: "Project Default",
        fieldDefs: [{ key: "market", type: "text" }],
        rolePresets: [{ role: "Consulting", share: 0.5 }],
      }),
    );
    expect(JSON.parse(rateCardsResult.content)).toEqual([
      {
        id: "rc_2026",
        name: "Standard 2026",
        effectiveFrom: "2026-01-01",
        effectiveTo: null,
        lineCount: 12,
      },
    ]);
  });

  it("returns a stable assistant error when a blueprint cannot be resolved for read access", async () => {
    const ctx = createToolContext(
      {
        blueprint: {
          findUnique: vi.fn().mockResolvedValue(null),
          findFirst: vi.fn().mockResolvedValue(null),
        },
      },
      {
        userRole: SystemRole.ADMIN,
        permissions: [PermissionKey.VIEW_PLANNING],
      },
    );

    const result = await executeTool(
      "get_blueprint",
      JSON.stringify({ identifier: "Missing Blueprint" }),
      ctx,
    );

    expect(JSON.parse(result.content)).toEqual({
      error: "Blueprint not found: Missing Blueprint",
    });
  });
});
