import { beforeEach, describe, expect, it, vi } from "vitest";
import { listAssignmentBookings } from "@capakraken/application";

vi.mock("@capakraken/application", async (importOriginal) => {
  const actual = await importOriginal<typeof import("@capakraken/application")>();
  return {
    ...actual,
    approveEstimateVersion: vi.fn(),
    cloneEstimate: vi.fn(),
    commitDispoImportBatch: vi.fn(),
    countPlanningEntries: vi.fn().mockResolvedValue({ countsByRoleId: new Map() }),
    createEstimateExport: vi.fn(),
    createEstimatePlanningHandoff: vi.fn(),
    createEstimateRevision: vi.fn(),
    assessDispoImportReadiness: vi.fn(),
    loadResourceDailyAvailabilityContexts: vi.fn().mockResolvedValue(new Map()),
    getDashboardDemand: vi.fn().mockResolvedValue([]),
    getDashboardBudgetForecast: vi.fn().mockResolvedValue([]),
    getDashboardOverview: vi.fn(),
    getDashboardSkillGapSummary: vi.fn().mockResolvedValue({
      roleGaps: [],
      totalOpenPositions: 0,
      skillSupplyTop10: [],
      resourcesByRole: [],
    }),
    getDashboardProjectHealth: vi.fn().mockResolvedValue([]),
    getDashboardPeakTimes: vi.fn().mockResolvedValue([]),
    getDashboardTopValueResources: vi.fn().mockResolvedValue([]),
    getEstimateById: vi.fn(),
    listAssignmentBookings: vi.fn().mockResolvedValue([]),
    stageDispoImportBatch: vi.fn(),
    submitEstimateVersion: vi.fn(),
    updateEstimateDraft: vi.fn(),
  };
});

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

describe("assistant insight anomaly tools", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    vi.mocked(listAssignmentBookings).mockResolvedValue([]);
  });

  it("returns anomaly details and count from the insights-backed detector", async () => {
    vi.useFakeTimers();
    vi.setSystemTime(new Date("2026-03-29T12:00:00.000Z"));

    try {
      const ctx = createToolContext({
        project: {
          findMany: vi.fn().mockResolvedValue([
            {
              id: "project_1",
              name: "Apollo",
              budgetCents: 100_000,
              startDate: new Date("2026-03-01T00:00:00.000Z"),
              endDate: new Date("2026-03-31T00:00:00.000Z"),
              demandRequirements: [
                {
                  id: "demand_1",
                  headcount: 3,
                  startDate: new Date("2026-03-20T00:00:00.000Z"),
                  endDate: new Date("2026-04-05T00:00:00.000Z"),
                  status: "CONFIRMED",
                  _count: { assignments: 1 },
                },
              ],
              assignments: [
                {
                  id: "assignment_1",
                  resourceId: "res_1",
                  startDate: new Date("2026-03-01T00:00:00.000Z"),
                  endDate: new Date("2026-04-05T00:00:00.000Z"),
                  hoursPerDay: 12,
                  dailyCostCents: 10_000,
                  status: "ACTIVE",
                },
              ],
            },
          ]),
        },
        resource: {
          findMany: vi.fn().mockResolvedValue([
            {
              id: "res_1",
              displayName: "Peter Parker",
              availability: {
                monday: 8,
                tuesday: 8,
                wednesday: 8,
                thursday: 8,
                friday: 8,
              },
            },
          ]),
        },
        assignment: {
          findMany: vi.fn().mockResolvedValue([
            {
              resourceId: "res_1",
              hoursPerDay: 12,
            },
          ]),
        },
      });

      const result = await executeTool("detect_anomalies", "{}", ctx);
      const parsed = JSON.parse(result.content) as {
        count: number;
        anomalies: Array<{ type: string; severity: string; entityName: string }>;
      };

      expect(parsed.count).toBe(4);
      expect(parsed.anomalies).toEqual([
        expect.objectContaining({
          type: "budget",
          severity: "critical",
          entityName: "Apollo",
        }),
        expect.objectContaining({
          type: "staffing",
          severity: "critical",
          entityName: "Apollo",
        }),
        expect.objectContaining({
          type: "utilization",
          severity: "critical",
          entityName: "Peter Parker",
        }),
        expect.objectContaining({
          type: "timeline",
          severity: "warning",
          entityName: "Apollo",
        }),
      ]);
    } finally {
      vi.useRealTimers();
    }
  });
});
