import { AllocationStatus } from "@nexus/shared";
import { describe, expect, it } from "vitest";
import { findCapacityWindows, analyzeUtilization } from "../capacity-analyzer.js";
import type { CapacityAnalysisInput } from "../capacity-analyzer.js";

const standardAvailability = {
  sunday: 0,
  monday: 8,
  tuesday: 8,
  wednesday: 8,
  thursday: 8,
  friday: 8,
  saturday: 0,
};

/**
 * Performance regression test.
 * 50 resources × 20 allocations × 365 days must complete in under 500 ms.
 */
describe("capacity-analyzer performance", () => {
  it("analyzeUtilization: 50 resources × 20 allocations × 365 days < 500 ms", () => {
    const analysisStart = new Date("2026-01-01");
    const analysisEnd = new Date("2026-12-31");
    const periodMs = analysisEnd.getTime() - analysisStart.getTime();

    const resources: CapacityAnalysisInput[] = Array.from({ length: 50 }, (_, ri) => {
      const allocations = Array.from({ length: 20 }, (_, ai) => {
        // Distribute allocations pseudo-randomly across the year
        const offset = Math.floor(((ri * 20 + ai) / 1000) * periodMs);
        const start = new Date(analysisStart.getTime() + offset);
        const end = new Date(start.getTime() + 30 * 24 * 60 * 60 * 1000); // 30-day blocks
        return {
          startDate: start > analysisEnd ? analysisStart : start,
          endDate: end > analysisEnd ? analysisEnd : end,
          hoursPerDay: 4,
          status: AllocationStatus.CONFIRMED,
          projectName: `Project-${ri}-${ai}`,
          isChargeable: ai % 2 === 0,
        };
      });

      return {
        resource: {
          id: `res-${ri}`,
          displayName: `Resource ${ri}`,
          chargeabilityTarget: 80,
          availability: standardAvailability,
        },
        allocations,
        analysisStart,
        analysisEnd,
      };
    });

    const t0 = performance.now();
    for (const input of resources) {
      analyzeUtilization(input);
    }
    const elapsed = performance.now() - t0;

    expect(elapsed).toBeLessThan(500);
  });

  it("findCapacityWindows: 50 resources × 20 allocations × 365 days < 500 ms", () => {
    const searchStart = new Date("2026-01-01");
    const searchEnd = new Date("2026-12-31");
    const periodMs = searchEnd.getTime() - searchStart.getTime();

    const simpleResource = {
      id: "res-perf",
      displayName: "Perf Resource",
      availability: standardAvailability,
    };

    const t0 = performance.now();

    for (let ri = 0; ri < 50; ri++) {
      const allocations = Array.from({ length: 20 }, (_, ai) => {
        const offset = Math.floor(((ri * 20 + ai) / 1000) * periodMs);
        const start = new Date(searchStart.getTime() + offset);
        const end = new Date(start.getTime() + 30 * 24 * 60 * 60 * 1000);
        return {
          startDate: start > searchEnd ? searchStart : start,
          endDate: end > searchEnd ? searchEnd : end,
          hoursPerDay: 4,
          status: AllocationStatus.CONFIRMED,
        };
      });

      findCapacityWindows(simpleResource, allocations, searchStart, searchEnd);
    }

    const elapsed = performance.now() - t0;

    expect(elapsed).toBeLessThan(500);
  });
});
