import { describe, expect, it } from "vitest";
import { AllocationStatus, type AllocationWithDetails } from "@capakraken/shared";
import { buildAllocationReadModel } from "../index.js";

function makeAllocation(overrides: Partial<AllocationWithDetails>): AllocationWithDetails {
  return {
    id: "alloc_1",
    resourceId: "res_1",
    projectId: "proj_1",
    startDate: new Date("2026-03-01T00:00:00.000Z"),
    endDate: new Date("2026-03-05T00:00:00.000Z"),
    hoursPerDay: 8,
    percentage: 100,
    role: "Compositor",
    roleId: "role_1",
    isPlaceholder: false,
    headcount: 1,
    dailyCostCents: 12_000,
    status: AllocationStatus.PROPOSED,
    metadata: {},
    createdAt: new Date("2026-03-01T00:00:00.000Z"),
    updatedAt: new Date("2026-03-01T00:00:00.000Z"),
    resource: {
      id: "res_1",
      displayName: "Alice",
      eid: "E-001",
      lcrCents: 15_000,
    },
    project: {
      id: "proj_1",
      name: "Project One",
      shortCode: "P1",
      status: "ACTIVE",
      endDate: new Date("2026-03-31T00:00:00.000Z"),
    },
    roleEntity: {
      id: "role_1",
      name: "Compositor",
      color: "#111111",
    },
    ...overrides,
  };
}

describe("allocation read model", () => {
  it("splits assignments from placeholder demand rows", () => {
    const input: AllocationWithDetails[] = [
      makeAllocation({ id: "assign_1" }),
      makeAllocation({
        id: "demand_1",
        resourceId: null,
        isPlaceholder: true,
        headcount: 3,
        dailyCostCents: 0,
        resource: null,
      }),
    ];

    const result = buildAllocationReadModel(input);

    expect(result.allocations).toHaveLength(2);
    expect(result.assignments).toHaveLength(1);
    expect(result.demands).toHaveLength(1);
    expect(result.assignments[0]).toMatchObject({
      id: "assign_1",
      kind: "assignment",
      sourceAllocationId: "assign_1",
      resourceId: "res_1",
      isPlaceholder: false,
    });
    expect(result.demands[0]).toMatchObject({
      id: "demand_1",
      kind: "demand",
      sourceAllocationId: "demand_1",
      resourceId: null,
      isPlaceholder: true,
      requestedHeadcount: 3,
      unfilledHeadcount: 3,
    });
  });

  it("treats null-resource rows as demand for legacy safety", () => {
    const input: AllocationWithDetails[] = [
      makeAllocation({
        id: "legacy_1",
        resourceId: null,
        isPlaceholder: false,
        headcount: 2,
        dailyCostCents: 0,
        resource: null,
      }),
    ];

    const result = buildAllocationReadModel(input);

    expect(result.assignments).toEqual([]);
    expect(result.demands).toHaveLength(1);
    expect(result.demands[0]?.sourceAllocationId).toBe("legacy_1");
  });
});
