import { beforeEach, describe, expect, it, vi } from "vitest";
import { PermissionKey } 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([]),
  };
});

vi.mock("../sse/event-bus.js", () => ({
  emitAllocationCreated: vi.fn(),
  emitAllocationDeleted: vi.fn(),
  emitAllocationUpdated: vi.fn(),
  emitProjectShifted: vi.fn(),
}));

vi.mock("../lib/budget-alerts.js", () => ({
  checkBudgetThresholds: vi.fn(),
}));

vi.mock("../lib/cache.js", () => ({
  invalidateDashboardCache: vi.fn(),
}));

import { executeTool } from "../router/assistant-tools.js";
import { createToolContext } from "./assistant-tools-advanced-timeline-test-helpers.js";

describe("assistant advanced timeline entries view tool", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("returns timeline entries view with demand, assignment, and holiday overlay context", async () => {
    const ctx = createToolContext(
      {
        demandRequirement: {
          findMany: vi.fn().mockResolvedValue([
            {
              id: "dem_1",
              projectId: "project_1",
              resourceId: null,
              role: "Artist",
              hoursPerDay: 8,
              startDate: new Date("2026-01-05T00:00:00.000Z"),
              endDate: new Date("2026-01-09T00:00:00.000Z"),
              status: "OPEN",
              metadata: null,
              project: {
                id: "project_1",
                name: "Gelddruckmaschine",
                shortCode: "GDM",
                orderType: "CHARGEABLE",
                clientId: "client_1",
                budgetCents: 0,
                winProbability: 100,
                status: "ACTIVE",
                startDate: new Date("2026-01-05T00:00:00.000Z"),
                endDate: new Date("2026-01-16T00:00:00.000Z"),
                staffingReqs: null,
                responsiblePerson: "Larissa",
                color: "#fff",
              },
              roleEntity: null,
            },
          ]),
        },
        assignment: {
          findMany: vi.fn().mockResolvedValue([
            {
              id: "asg_by",
              projectId: "project_1",
              resourceId: "res_by",
              role: "Artist",
              hoursPerDay: 8,
              startDate: new Date("2026-01-05T00:00:00.000Z"),
              endDate: new Date("2026-01-09T00:00:00.000Z"),
              status: "CONFIRMED",
              metadata: null,
              resource: {
                id: "res_by",
                displayName: "Bayern User",
                eid: "EMP-BY",
                chapter: "Delivery",
                lcrCents: 10000,
              },
              project: {
                id: "project_1",
                name: "Gelddruckmaschine",
                shortCode: "GDM",
                orderType: "CHARGEABLE",
                clientId: "client_1",
                budgetCents: 0,
                winProbability: 100,
                status: "ACTIVE",
                startDate: new Date("2026-01-05T00:00:00.000Z"),
                endDate: new Date("2026-01-16T00:00:00.000Z"),
                staffingReqs: null,
                responsiblePerson: "Larissa",
                color: "#fff",
              },
              roleEntity: null,
            },
            {
              id: "asg_hh",
              projectId: "project_1",
              resourceId: "res_hh",
              role: "Artist",
              hoursPerDay: 8,
              startDate: new Date("2026-01-05T00:00:00.000Z"),
              endDate: new Date("2026-01-09T00:00:00.000Z"),
              status: "CONFIRMED",
              metadata: null,
              resource: {
                id: "res_hh",
                displayName: "Hamburg User",
                eid: "EMP-HH",
                chapter: "Delivery",
                lcrCents: 10000,
              },
              project: {
                id: "project_1",
                name: "Gelddruckmaschine",
                shortCode: "GDM",
                orderType: "CHARGEABLE",
                clientId: "client_1",
                budgetCents: 0,
                winProbability: 100,
                status: "ACTIVE",
                startDate: new Date("2026-01-05T00:00:00.000Z"),
                endDate: new Date("2026-01-16T00:00:00.000Z"),
                staffingReqs: null,
                responsiblePerson: "Larissa",
                color: "#fff",
              },
              roleEntity: null,
            },
          ]),
        },
        resource: {
          findMany: vi.fn().mockResolvedValue([
            {
              id: "res_by",
              countryId: "country_de",
              federalState: "BY",
              metroCityId: "city_munich",
              country: { code: "DE" },
              metroCity: { name: "Muenchen" },
            },
            {
              id: "res_hh",
              countryId: "country_de",
              federalState: "HH",
              metroCityId: "city_hamburg",
              country: { code: "DE" },
              metroCity: { name: "Hamburg" },
            },
          ]),
        },
        project: {
          findMany: vi.fn(),
        },
      },
      [PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS],
    );

    const result = await executeTool(
      "get_timeline_entries_view",
      JSON.stringify({
        startDate: "2026-01-05",
        endDate: "2026-01-09",
        projectIds: ["project_1"],
      }),
      ctx,
    );

    const parsed = JSON.parse(result.content) as {
      summary: {
        demandCount: number;
        assignmentCount: number;
        overlayCount: number;
        resourceCount: number;
      };
      demands: Array<{ id: string }>;
      assignments: Array<{ id: string }>;
      holidayOverlays: Array<{ resourceId: string; startDate: string; note: string; scope: string }>;
    };

    expect(parsed.summary).toEqual(
      expect.objectContaining({
        demandCount: 1,
        assignmentCount: 2,
        overlayCount: 1,
        resourceCount: 2,
      }),
    );
    expect(parsed.demands).toHaveLength(1);
    expect(parsed.assignments).toHaveLength(2);
    expect(parsed.holidayOverlays).toEqual([
      expect.objectContaining({
        resourceId: "res_by",
        startDate: "2026-01-06",
        note: "Heilige Drei Könige",
        scope: "STATE",
      }),
    ]);
  });
});
