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 { basePurchaseRequisition, basePurchaseRequisitionLine } from "../testing/fixtures";
import { run } from "./getPurchaseRequisition";

describe("getPurchaseRequisition", () => {
  it("returns purchase requisition when found by id", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([basePurchaseRequisition], [basePurchaseRequisitionLine]);

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

    expect(purchaseRequisition).not.toBeNull();
    expect(purchaseRequisition).toMatchObject({ id: basePurchaseRequisition.id });
  });

  it("returns lines and estimated totals with the requisition", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([basePurchaseRequisition], [basePurchaseRequisitionLine]);

    const result = await run(mock.db, { id: basePurchaseRequisition.id });
    const { purchaseRequisition } = expectOk<{
      purchaseRequisition: {
        lines: { id: string; estimatedLineTotal: number }[];
        estimatedTotal: number;
      };
    }>(result as never);

    expect(purchaseRequisition.lines).toHaveLength(1);
    expect(purchaseRequisition.lines[0]).toMatchObject({
      id: basePurchaseRequisitionLine.id,
      estimatedLineTotal: "50", // 10 * 5
    });
    expect(purchaseRequisition.estimatedTotal).toBe("50");
  });

  it("returns suggested supplier on lines when present", async () => {
    const lineWithSupplier = {
      ...basePurchaseRequisitionLine,
      id: "pr-line-2",
      suggestedSupplierId: "supplier-1",
    };
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([basePurchaseRequisition], [lineWithSupplier]);

    const result = await run(mock.db, { id: basePurchaseRequisition.id });
    const { purchaseRequisition } = expectOk<{
      purchaseRequisition: {
        lines: { suggestedSupplierId: string | null }[];
      };
    }>(result as never);

    expect(purchaseRequisition.lines[0].suggestedSupplierId).toBe("supplier-1");
  });

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

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

    expect(purchaseRequisition).toBeNull();
  });
});
