import { describe, expect, it } from "vitest";
import {
  isChargeabilityActualBooking,
  isChargeabilityRelevantProject,
  isImportedTbdDraftProject,
} from "../use-cases/allocation/chargeability-bookings.js";

type ProjectLike = {
  status: string;
  dynamicFields: Record<string, unknown> | null;
};

type BookingLike = {
  status: string;
  project: ProjectLike;
};

describe("isImportedTbdDraftProject", () => {
  it("returns true for a DRAFT project with dispoImport.isTbd=true", () => {
    const project: ProjectLike = {
      status: "DRAFT",
      dynamicFields: { dispoImport: { isTbd: true } },
    };
    expect(isImportedTbdDraftProject(project as never)).toBe(true);
  });

  it("returns false for a DRAFT project without the isTbd flag", () => {
    const project: ProjectLike = {
      status: "DRAFT",
      dynamicFields: { dispoImport: { isTbd: false } },
    };
    expect(isImportedTbdDraftProject(project as never)).toBe(false);
  });

  it("returns false for a non-DRAFT project even with isTbd=true", () => {
    const project: ProjectLike = {
      status: "ACTIVE",
      dynamicFields: { dispoImport: { isTbd: true } },
    };
    expect(isImportedTbdDraftProject(project as never)).toBe(false);
  });

  it("returns false when dynamicFields is null", () => {
    const project: ProjectLike = { status: "DRAFT", dynamicFields: null };
    expect(isImportedTbdDraftProject(project as never)).toBe(false);
  });
});

describe("isChargeabilityRelevantProject", () => {
  it("returns true for ACTIVE projects regardless of includeProposed", () => {
    const project: ProjectLike = { status: "ACTIVE", dynamicFields: null };
    expect(isChargeabilityRelevantProject(project as never, false)).toBe(true);
    expect(isChargeabilityRelevantProject(project as never, true)).toBe(true);
  });

  it("returns false for CANCELLED projects", () => {
    const project: ProjectLike = { status: "CANCELLED", dynamicFields: null };
    expect(isChargeabilityRelevantProject(project as never, true)).toBe(false);
  });

  it("returns true for a TBD DRAFT project when includeProposed=true", () => {
    const project: ProjectLike = {
      status: "DRAFT",
      dynamicFields: { dispoImport: { isTbd: true } },
    };
    expect(isChargeabilityRelevantProject(project as never, true)).toBe(true);
  });

  it("returns false for a TBD DRAFT project when includeProposed=false", () => {
    const project: ProjectLike = {
      status: "DRAFT",
      dynamicFields: { dispoImport: { isTbd: true } },
    };
    expect(isChargeabilityRelevantProject(project as never, false)).toBe(false);
  });
});

describe("isChargeabilityActualBooking", () => {
  const activeProject: ProjectLike = { status: "ACTIVE", dynamicFields: null };
  const cancelledProject: ProjectLike = { status: "CANCELLED", dynamicFields: null };

  it("returns true for a CONFIRMED booking on an ACTIVE project", () => {
    const booking: BookingLike = { status: "CONFIRMED", project: activeProject };
    expect(isChargeabilityActualBooking(booking as never, false)).toBe(true);
  });

  it("returns true for an ACTIVE booking on an ACTIVE project", () => {
    const booking: BookingLike = { status: "ACTIVE", project: activeProject };
    expect(isChargeabilityActualBooking(booking as never, false)).toBe(true);
  });

  it("includes PROPOSED bookings only when includeProposed=true", () => {
    const booking: BookingLike = { status: "PROPOSED", project: activeProject };
    expect(isChargeabilityActualBooking(booking as never, false)).toBe(false);
    expect(isChargeabilityActualBooking(booking as never, true)).toBe(true);
  });

  it("returns false for any booking on a CANCELLED project", () => {
    const booking: BookingLike = { status: "CONFIRMED", project: cancelledProject };
    expect(isChargeabilityActualBooking(booking as never, true)).toBe(false);
  });
});
