import { describe, expect, it, vi } from "vitest";

const { calculateAllocationMock } = vi.hoisted(() => ({
  calculateAllocationMock: vi.fn(),
}));

vi.mock("@capakraken/engine", async (importOriginal) => {
  const actual = await importOriginal<typeof import("@capakraken/engine")>();
  return {
    ...actual,
    calculateAllocation: calculateAllocationMock,
  };
});

vi.mock("../router/timeline-cost-load-support.js", () => ({
  buildTimelineAbsenceDays: vi.fn(),
  loadTimelineCalculationRules: vi.fn(),
}));

import {
  buildTimelineAbsenceDays,
  loadTimelineCalculationRules,
} from "../router/timeline-cost-load-support.js";
import { calculateTimelineAllocationDailyCost } from "../router/timeline-cost-support.js";

const buildTimelineAbsenceDaysMock = vi.mocked(buildTimelineAbsenceDays);
const loadTimelineCalculationRulesMock = vi.mocked(loadTimelineCalculationRules);

describe("timeline cost support", () => {
  it("builds timeline allocation daily cost from loaded absences and rules", async () => {
    buildTimelineAbsenceDaysMock.mockResolvedValueOnce({
      absenceDays: [{ date: new Date("2026-04-03T00:00:00.000Z"), type: "VACATION" }],
      legacyVacationDates: [new Date("2026-04-03T00:00:00.000Z")],
    });
    loadTimelineCalculationRulesMock.mockResolvedValueOnce([{ id: "rule_1" }] as never);
    calculateAllocationMock.mockReturnValueOnce({ dailyCostCents: 54_321 });

    await expect(
      calculateTimelineAllocationDailyCost({
        db: {} as never,
        resourceId: "resource_1",
        lcrCents: 5_000,
        hoursPerDay: 8,
        startDate: new Date("2026-04-01T00:00:00.000Z"),
        endDate: new Date("2026-04-10T00:00:00.000Z"),
        availability: {
          monday: 8,
          tuesday: 8,
          wednesday: 8,
          thursday: 8,
          friday: 8,
        } as never,
        includeSaturday: true,
      }),
    ).resolves.toBe(54_321);

    expect(buildTimelineAbsenceDaysMock).toHaveBeenCalledWith(
      {},
      "resource_1",
      new Date("2026-04-01T00:00:00.000Z"),
      new Date("2026-04-10T00:00:00.000Z"),
    );
    expect(loadTimelineCalculationRulesMock).toHaveBeenCalledWith({});
    expect(calculateAllocationMock).toHaveBeenCalledWith(
      expect.objectContaining({
        lcrCents: 5_000,
        hoursPerDay: 8,
        includeSaturday: true,
        vacationDates: [new Date("2026-04-03T00:00:00.000Z")],
        absenceDays: [{ date: new Date("2026-04-03T00:00:00.000Z"), type: "VACATION" }],
        calculationRules: [{ id: "rule_1" }],
      }),
    );
  });
});
