import { createKyselyMock } from "@tailor-platform/sdk/vitest";
import { describe, expect, it } from "vitest";
import type { Namespace } from "../generated/kysely-tailordb";
import { expectOk } from "../testing/commandTestUtils";
import { basePurchaseOrder, basePurchaseOrderLine } from "../testing/fixtures";
import { run } from "./getPurchaseOrder";

describe("getPurchaseOrder", () => {
  it("returns purchase order when found by id", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([basePurchaseOrder], [basePurchaseOrderLine]);

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

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

  it("returns lines with the order", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([basePurchaseOrder], [basePurchaseOrderLine]);

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

    expect(purchaseOrder.lines).toHaveLength(1);
    expect(purchaseOrder.lines[0]).toMatchObject({ id: basePurchaseOrderLine.id });
  });

  it("returns null when purchase order is not found", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([]);

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

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

  it("returns billed quantities per line without receipt-derived fields", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([basePurchaseOrder], [{ ...basePurchaseOrderLine, billedQuantity: "2" }]);

    const result = await run(mock.db, { id: basePurchaseOrder.id });
    const { purchaseOrder } = expectOk<{
      purchaseOrder: {
        lines: Record<string, unknown>[];
      };
    }>(result as never);

    expect(purchaseOrder.lines[0]).toMatchObject({
      billedQuantity: "2",
      remainingQuantityToBill: "8", // 10 - 2
    });
    expect(purchaseOrder.lines[0]).not.toHaveProperty("receivedQuantity");
    expect(purchaseOrder.lines[0]).not.toHaveProperty("remainingQuantityToReceive");
    expect(purchaseOrder.lines[0]).not.toHaveProperty("remainingReceivedQuantityToBill");
  });

  it("does not expose remaining received quantity from the purchase query", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([basePurchaseOrder], [{ ...basePurchaseOrderLine, billedQuantity: "5" }]);

    const result = await run(mock.db, { id: basePurchaseOrder.id });
    const { purchaseOrder } = expectOk<{
      purchaseOrder: {
        lines: Record<string, unknown>[];
      };
    }>(result as never);

    expect(purchaseOrder.lines[0]).toMatchObject({
      remainingQuantityToBill: "5",
    });
    expect(purchaseOrder.lines[0]).not.toHaveProperty("remainingReceivedQuantityToBill");
  });
});
