import { describe, expect, it } from "vitest";
import { calculateAllocation } from "../allocation/calculator.js";
import { validateAvailability } from "../allocation/availability-validator.js";

// Resource available Mon–Sat (6h Saturday)
const satAvailability = {
  monday: 8,
  tuesday: 8,
  wednesday: 8,
  thursday: 8,
  friday: 8,
  saturday: 6,
};

// Week Mon 2025-01-06 to Sat 2025-01-11
const MON = new Date("2025-01-06");
const SAT = new Date("2025-01-11");

describe("calculateAllocation — includeSaturday", () => {
  it("excludes Saturday by default when resource has saturday availability", () => {
    const result = calculateAllocation({
      lcrCents: 10000,
      hoursPerDay: 8,
      startDate: MON,
      endDate: SAT,
      availability: satAvailability,
      // includeSaturday not set → defaults to false
    });

    expect(result.workingDays).toBe(5); // Mon–Fri only
    expect(result.totalHours).toBe(40);
  });

  it("includes Saturday when includeSaturday is true", () => {
    const result = calculateAllocation({
      lcrCents: 10000,
      hoursPerDay: 8,
      startDate: MON,
      endDate: SAT,
      availability: satAvailability,
      includeSaturday: true,
    });

    expect(result.workingDays).toBe(6); // Mon–Sat
    // Saturday capped at 6h (resource availability)
    expect(result.totalHours).toBe(46); // 5×8 + 6
    expect(result.totalCostCents).toBe(460000); // 46h × 10000 cents/h
  });

  it("includeSaturday: false explicitly still excludes Saturday", () => {
    const result = calculateAllocation({
      lcrCents: 10000,
      hoursPerDay: 8,
      startDate: MON,
      endDate: SAT,
      availability: satAvailability,
      includeSaturday: false,
    });

    expect(result.workingDays).toBe(5);
  });

  it("does not add Saturday if resource has no saturday availability", () => {
    const noSatAvailability = { monday: 8, tuesday: 8, wednesday: 8, thursday: 8, friday: 8 };
    const result = calculateAllocation({
      lcrCents: 10000,
      hoursPerDay: 8,
      startDate: MON,
      endDate: SAT,
      availability: noSatAvailability,
      includeSaturday: true,
    });

    expect(result.workingDays).toBe(5); // Saturday still 0 because resource unavailable
  });
});

describe("validateAvailability — includeSaturday", () => {
  it("skips Saturday conflicts when includeSaturday is false", () => {
    // Resource available only on Saturday (Mon–Fri: 0)
    const satOnlyAvail = { monday: 0, tuesday: 0, wednesday: 0, thursday: 0, friday: 0, saturday: 8 };
    const result = validateAvailability(SAT, SAT, 8, satOnlyAvail, [], false);

    // Saturday is excluded, so no conflicts (day treated as non-working)
    expect(result.valid).toBe(true);
    expect(result.totalConflictDays).toBe(0);
  });

  it("detects conflict on Saturday when includeSaturday is true", () => {
    const result = validateAvailability(
      SAT,
      SAT,
      8, // request 8h
      satAvailability, // Saturday: 6h available
      [],
      true,
    );

    // 8h requested > 6h available → conflict
    expect(result.valid).toBe(false);
    expect(result.totalConflictDays).toBe(1);
    expect(result.conflicts[0]?.overageHours).toBe(2);
  });

  it("no conflict on Saturday within availability when includeSaturday true", () => {
    const result = validateAvailability(SAT, SAT, 4, satAvailability, [], true);

    expect(result.valid).toBe(true);
  });
});
