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 dashboard layout tools", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("reads dashboard layout through the real user router path", async () => {
    const db = {
      user: {
        findUnique: vi.fn().mockResolvedValue({
          dashboardLayout: {
            version: 2,
            gridCols: 12,
            widgets: [
              // Valid widget type so normalization preserves it
              { id: "stat-1", type: "stat-cards", x: 0, y: 0, w: 12, h: 3 },
            ],
          },
          updatedAt: new Date("2026-03-30T18:00:00.000Z"),
        }),
      },
    };
    const ctx = createToolContext(db, SystemRole.ADMIN);

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

    expect(db.user.findUnique).toHaveBeenCalledWith({
      where: { id: "user_1" },
      select: { dashboardLayout: true, updatedAt: true },
    });
    const parsed = JSON.parse(result.content) as { layout: { widgets: unknown[] } | null };
    expect(parsed.layout).not.toBeNull();
    expect(parsed.layout?.widgets).toHaveLength(1);
  });

  it("returns null layout when stored widgets have no valid type (bug #27 guard)", async () => {
    const db = {
      user: {
        findUnique: vi.fn().mockResolvedValue({
          dashboardLayout: {
            widgets: [{ id: "peakTimes", position: { x: 0, y: 0, w: 4, h: 3 } }],
          },
          updatedAt: new Date("2026-03-30T18:00:00.000Z"),
        }),
      },
    };
    const ctx = createToolContext(db, SystemRole.ADMIN);
    const result = await executeTool("get_dashboard_layout", "{}", ctx);
    // Unknown widget type → normalises to empty → client gets null to use default layout
    expect(JSON.parse(result.content)).toMatchObject({ layout: null });
  });

  it("saves dashboard layout through the real user router path", async () => {
    const db = {
      user: {
        update: vi.fn().mockResolvedValue({
          updatedAt: new Date("2026-03-30T19:00:00.000Z"),
        }),
      },
    };
    const ctx = createToolContext(db, SystemRole.ADMIN);
    const layout = {
      version: 2,
      gridCols: 12,
      widgets: [],
    };

    const result = await executeTool(
      "save_dashboard_layout",
      JSON.stringify({ layout }),
      ctx,
    );

    expect(db.user.update).toHaveBeenCalledWith({
      where: { id: "user_1" },
      data: { dashboardLayout: layout },
      select: { updatedAt: true },
    });
    expect(JSON.parse(result.content)).toEqual({
      success: true,
      updatedAt: "2026-03-30T19:00:00.000Z",
      message: "Saved dashboard layout.",
    });
    expect(result.action).toEqual({
      type: "invalidate",
      scope: ["dashboard"],
    });
  });
});
