import { describe, expect, it } from "vitest";
import { createMockDb } from "../../../testing/index";
import type { DB } from "../generated/kysely-tailordb";
import { basePurchaseOrder, basePurchaseOrderLines } from "../testing/fixtures";
import { expectOk } from "../testing/commandTestUtils";
import { run } from "./getPurchaseOrder";

describe("getPurchaseOrder", () => {
  it("returns purchase order when found by id", async () => {
    const { db, spies } = createMockDb<DB>();
    spies.select.mockReturnValueOnce(basePurchaseOrder);

    const result = await run(db, { id: basePurchaseOrder.id });
    const { purchaseOrder } = expectOk<{ purchaseOrder: unknown }>(result as never);

    expect(purchaseOrder).not.toBeNull();
    expect(purchaseOrder).toMatchObject({ id: basePurchaseOrder.id });
  });

  it("returns purchase order when found by company and external supplier order reference", async () => {
    const { db, spies } = createMockDb<DB>();
    spies.select.mockReturnValueOnce(basePurchaseOrder);

    const result = await run(db, {
      companyId: basePurchaseOrder.companyId,
      externalSupplierOrderReference: basePurchaseOrder.externalSupplierOrderReference,
    });
    const { purchaseOrder } = expectOk<{ purchaseOrder: unknown }>(result as never);

    expect(purchaseOrder).not.toBeNull();
    expect(purchaseOrder).toMatchObject({ id: basePurchaseOrder.id });
  });

  it("returns lines and fulfillment totals with the order", async () => {
    const { db, spies } = createMockDb<DB>();
    spies.select.mockReturnValueOnce(basePurchaseOrder);

    const result = await run(db, { id: basePurchaseOrder.id });
    const { purchaseOrder } = expectOk<{
      purchaseOrder: {
        lines: unknown[];
        paymentTermSnapshot: unknown;
        fulfillmentTotals: { totalOrdered: number; totalReceived: number; totalBilled: number };
      };
    }>(result as never);

    expect(purchaseOrder.lines).toEqual(basePurchaseOrderLines);
    expect(purchaseOrder.paymentTermSnapshot).not.toBeNull();
    expect(purchaseOrder.fulfillmentTotals).toEqual({
      totalOrdered: 10,
      totalReceived: 0,
      totalBilled: 0,
    });
  });

  it("returns null when purchase order is not found", async () => {
    const { db, spies } = createMockDb<DB>();
    spies.select.mockReturnValueOnce(undefined);

    const result = await run(db, { id: "non-existent-id" });
    const { purchaseOrder } = expectOk<{ purchaseOrder: null }>(result as never);

    expect(purchaseOrder).toBeNull();
  });
});
