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,
    approveEstimateVersion: vi.fn(),
    cloneEstimate: vi.fn(),
    createEstimateExport: vi.fn(),
    createEstimatePlanningHandoff: vi.fn(),
    createEstimateRevision: vi.fn(),
    getDashboardBudgetForecast: vi.fn().mockResolvedValue([]),
    getDashboardPeakTimes: vi.fn().mockResolvedValue([]),
    getEstimateById: vi.fn(),
    listAssignmentBookings: vi.fn().mockResolvedValue([]),
    submitEstimateVersion: vi.fn(),
    updateEstimateDraft: vi.fn(),
  };
});

import { executeTool } from "../router/assistant-tools.js";
import {
  createToolContext,
  resetEstimateToolMocks,
} from "./assistant-tools-estimate-test-helpers.js";

describe("assistant estimate version snapshot tools", () => {
  beforeEach(() => {
    resetEstimateToolMocks();
  });

  it("reads estimate version snapshots through the real estimate router, requires viewCosts, and rejects plain users", async () => {
    const db = {
      estimate: {
        findUnique: vi.fn().mockResolvedValue({
          id: "est_1",
          name: "North Cluster Estimate",
          status: "APPROVED",
          baseCurrency: "EUR",
          versions: [
            {
              id: "ver_4",
              versionNumber: 4,
              label: "Rev 4",
              status: "APPROVED",
              notes: "Latest",
              lockedAt: new Date("2026-03-29T00:00:00.000Z"),
              createdAt: new Date("2026-03-28T00:00:00.000Z"),
              updatedAt: new Date("2026-03-29T00:00:00.000Z"),
              assumptions: [
                { id: "ass_1", category: "DELIVERY", key: "onsite", label: "Onsite support" },
              ],
              scopeItems: [
                { id: "scope_1", scopeType: "EPIC", sequenceNo: 1, name: "Pipeline" },
              ],
              demandLines: [
                {
                  id: "dl_1",
                  name: "Modeling",
                  chapter: "3D",
                  hours: 40,
                  costTotalCents: 400000,
                  priceTotalCents: 600000,
                  currency: "EUR",
                },
              ],
              resourceSnapshots: [
                {
                  id: "snap_1",
                  displayName: "Alice",
                  chapter: "3D",
                  currency: "EUR",
                  lcrCents: 10000,
                  ucrCents: 15000,
                },
              ],
              exports: [
                {
                  id: "exp_1",
                  format: "XLSX",
                  fileName: "estimate.xlsx",
                  createdAt: new Date("2026-03-29T10:00:00.000Z"),
                },
              ],
            },
          ],
        }),
      },
    };
    const controllerCtx = createToolContext(db, {
      userRole: SystemRole.CONTROLLER,
      permissions: [PermissionKey.VIEW_COSTS],
    });
    const controllerWithoutCostsCtx = createToolContext(db, {
      userRole: SystemRole.CONTROLLER,
      permissions: [],
    });
    const userCtx = createToolContext({}, { userRole: SystemRole.USER });

    const successResult = await executeTool(
      "get_estimate_version_snapshot",
      JSON.stringify({ estimateId: "est_1", versionId: "ver_4" }),
      controllerCtx,
    );
    const missingPermissionResult = await executeTool(
      "get_estimate_version_snapshot",
      JSON.stringify({ estimateId: "est_1", versionId: "ver_4" }),
      controllerWithoutCostsCtx,
    );
    const deniedResult = await executeTool(
      "get_estimate_version_snapshot",
      JSON.stringify({ estimateId: "est_1", versionId: "ver_4" }),
      userCtx,
    );

    expect(db.estimate.findUnique).toHaveBeenCalledWith({
      where: { id: "est_1" },
      select: expect.objectContaining({
        id: true,
        versions: expect.objectContaining({
          where: { id: "ver_4" },
        }),
      }),
    });
    expect(JSON.parse(successResult.content)).toEqual(
      expect.objectContaining({
        estimate: expect.objectContaining({
          id: "est_1",
          baseCurrency: "EUR",
        }),
        version: expect.objectContaining({
          id: "ver_4",
          versionNumber: 4,
        }),
        totals: expect.objectContaining({
          hours: 40,
          costTotalCents: 400000,
          priceTotalCents: 600000,
        }),
        chapterBreakdown: [
          expect.objectContaining({
            chapter: "3D",
            lineCount: 1,
          }),
        ],
      }),
    );
    expect(JSON.parse(missingPermissionResult.content)).toEqual(
      expect.objectContaining({
        error: expect.stringContaining(PermissionKey.VIEW_COSTS),
      }),
    );
    expect(JSON.parse(deniedResult.content)).toEqual(
      expect.objectContaining({
        error: "You do not have permission to perform this action.",
      }),
    );
  });
});
