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 project shift preview tool", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("returns project shift preview details from the canonical timeline router", async () => {
    const projectFindUnique = vi.fn().mockImplementation((args: { where?: { id?: string; shortCode?: string }; select?: Record<string, unknown> }) => {
      if (args.where?.id === "GDM") {
        return Promise.resolve(null);
      }
      if (args.where?.shortCode === "GDM") {
        return Promise.resolve({
          id: "project_shift",
          name: "Gelddruckmaschine",
          shortCode: "GDM",
          status: "ACTIVE",
          responsiblePerson: "Larissa",
          startDate: new Date("2026-01-05T00:00:00.000Z"),
          endDate: new Date("2026-01-16T00:00:00.000Z"),
        });
      }
      if (args.select && "budgetCents" in args.select) {
        return Promise.resolve({
          id: "project_shift",
          budgetCents: 100000,
          winProbability: 100,
          startDate: new Date("2026-01-05T00:00:00.000Z"),
          endDate: new Date("2026-01-16T00:00:00.000Z"),
        });
      }

      return Promise.resolve({
        id: "project_shift",
        name: "Gelddruckmaschine",
        shortCode: "GDM",
        status: "ACTIVE",
        responsiblePerson: "Larissa",
        startDate: new Date("2026-01-05T00:00:00.000Z"),
        endDate: new Date("2026-01-16T00:00:00.000Z"),
      });
    });

    const ctx = createToolContext(
      {
        project: {
          findUnique: projectFindUnique,
          findFirst: vi.fn(),
        },
        demandRequirement: {
          findMany: vi.fn().mockResolvedValue([]),
        },
        assignment: {
          findMany: vi.fn().mockResolvedValue([]),
        },
      },
      [PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS],
    );

    const result = await executeTool(
      "preview_project_shift",
      JSON.stringify({
        projectIdentifier: "GDM",
        newStartDate: "2026-01-19",
        newEndDate: "2026-01-30",
      }),
      ctx,
    );

    expect(JSON.parse(result.content)).toEqual({
      project: {
        id: "project_shift",
        name: "Gelddruckmaschine",
        shortCode: "GDM",
        status: "ACTIVE",
        responsiblePerson: "Larissa",
        startDate: "2026-01-05",
        endDate: "2026-01-16",
      },
      requestedShift: {
        newStartDate: "2026-01-19",
        newEndDate: "2026-01-30",
      },
      preview: {
        valid: true,
        errors: [],
        warnings: [],
        conflictDetails: [],
        costImpact: {
          currentTotalCents: 0,
          newTotalCents: 0,
          deltaCents: 0,
          budgetCents: 100000,
          budgetUtilizationBefore: 0,
          budgetUtilizationAfter: 0,
          wouldExceedBudget: false,
        },
      },
    });
  });
});
