import { describe, expect, it } from "vitest";
import { getPlanningEntryMutationId } from "./planningEntryIds.js";

describe("getPlanningEntryMutationId", () => {
  // ---------------------------------------------------------------------------
  // Priority: entityId first
  // ---------------------------------------------------------------------------

  it("returns entityId when all three fields are present", () => {
    const result = getPlanningEntryMutationId({
      id: "id-1",
      entityId: "entity-1",
      sourceAllocationId: "alloc-1",
    });
    expect(result).toBe("entity-1");
  });

  it("returns entityId when sourceAllocationId is absent", () => {
    const result = getPlanningEntryMutationId({
      id: "id-1",
      entityId: "entity-1",
    });
    expect(result).toBe("entity-1");
  });

  it("returns entityId when sourceAllocationId is null", () => {
    const result = getPlanningEntryMutationId({
      id: "id-1",
      entityId: "entity-1",
      sourceAllocationId: null,
    });
    expect(result).toBe("entity-1");
  });

  // ---------------------------------------------------------------------------
  // Fallback: sourceAllocationId when entityId is absent/null/undefined
  // ---------------------------------------------------------------------------

  it("returns sourceAllocationId when entityId is null", () => {
    const result = getPlanningEntryMutationId({
      id: "id-1",
      entityId: null,
      sourceAllocationId: "alloc-1",
    });
    expect(result).toBe("alloc-1");
  });

  it("returns sourceAllocationId when entityId is undefined", () => {
    const result = getPlanningEntryMutationId({
      id: "id-1",
      entityId: undefined as string | undefined,
      sourceAllocationId: "alloc-1",
    } as Parameters<typeof getPlanningEntryMutationId>[0]);
    expect(result).toBe("alloc-1");
  });

  it("returns sourceAllocationId when entityId field is omitted", () => {
    const result = getPlanningEntryMutationId({
      id: "id-1",
      sourceAllocationId: "alloc-1",
    });
    expect(result).toBe("alloc-1");
  });

  // ---------------------------------------------------------------------------
  // Final fallback: id
  // ---------------------------------------------------------------------------

  it("returns id when both entityId and sourceAllocationId are null", () => {
    const result = getPlanningEntryMutationId({
      id: "id-1",
      entityId: null,
      sourceAllocationId: null,
    });
    expect(result).toBe("id-1");
  });

  it("returns id when both entityId and sourceAllocationId are undefined", () => {
    const result = getPlanningEntryMutationId({
      id: "id-1",
    } as Parameters<typeof getPlanningEntryMutationId>[0]);
    expect(result).toBe("id-1");
  });

  it("returns id when only id is provided", () => {
    const result = getPlanningEntryMutationId({ id: "id-only" });
    expect(result).toBe("id-only");
  });

  // ---------------------------------------------------------------------------
  // Return-type guarantee
  // ---------------------------------------------------------------------------

  it("always returns a string", () => {
    const cases = [
      { id: "x", entityId: "e", sourceAllocationId: "a" },
      { id: "x", entityId: null, sourceAllocationId: "a" },
      { id: "x", entityId: null, sourceAllocationId: null },
    ];
    cases.forEach((entry) => {
      expect(typeof getPlanningEntryMutationId(entry)).toBe("string");
    });
  });
});
