import { describe, expect, it } from "vitest";
import { createMockDb } from "../../../testing/index";
import type { Transaction } from "../generated/kysely-tailordb";
import { PurchaseOrderNotFoundError } from "../lib/errors.generated";
import { commandCtx, expectErr, expectOk, mockInventoryQueries } from "../testing/commandTestUtils";
import { basePurchaseOrder, basePurchaseOrderLine } from "../testing/fixtures";
import { recalculatePurchaseOrderReceiptStatusInternal } from "./purchaseOrder";

describe("recalculatePurchaseOrderReceiptStatusInternal", () => {
  it("updates receiptStatus from posted inventory receipt evidence", async () => {
    const { db, spies } = createMockDb<Transaction>();
    const line = { ...basePurchaseOrderLine, quantity: "10" };
    spies.select.mockReturnValueOnce(basePurchaseOrder).mockReturnValueOnce([line]);
    spies.update.mockReturnValueOnce({ ...basePurchaseOrder, receiptStatus: "PARTIALLY_RECEIVED" });

    const result = await recalculatePurchaseOrderReceiptStatusInternal(
      db,
      { purchaseOrderId: basePurchaseOrder.id },
      commandCtx,
      mockInventoryQueries({
        receiptEvidence: [
          {
            purchaseOrderLineId: line.id,
            inventoryExecutionLineId: "inventory-execution-line-1",
            inventoryExecutionId: "inventory-execution-1",
            quantity: "4",
            createdAt: new Date("2024-01-01T00:00:00.000Z"),
          },
        ],
      }),
    );

    expect(expectOk(result).purchaseOrder.receiptStatus).toBe("PARTIALLY_RECEIVED");
    expect(spies.set).toHaveBeenCalledWith(
      expect.objectContaining({ receiptStatus: "PARTIALLY_RECEIVED" }),
    );
  });

  it("marks the order received when evidence covers all ordered quantity", async () => {
    const { db, spies } = createMockDb<Transaction>();
    const line = { ...basePurchaseOrderLine, quantity: "10" };
    spies.select.mockReturnValueOnce(basePurchaseOrder).mockReturnValueOnce([line]);
    spies.update.mockReturnValueOnce({ ...basePurchaseOrder, receiptStatus: "RECEIVED" });

    const result = await recalculatePurchaseOrderReceiptStatusInternal(
      db,
      { purchaseOrderId: basePurchaseOrder.id },
      commandCtx,
      mockInventoryQueries({
        receiptEvidence: [
          {
            purchaseOrderLineId: line.id,
            inventoryExecutionLineId: "inventory-execution-line-1",
            inventoryExecutionId: "inventory-execution-1",
            quantity: "10",
            createdAt: new Date("2024-01-01T00:00:00.000Z"),
          },
        ],
      }),
    );

    expect(expectOk(result).purchaseOrder.receiptStatus).toBe("RECEIVED");
  });

  it("returns error when purchase order does not exist", async () => {
    const { db, spies } = createMockDb<Transaction>();
    spies.select.mockReturnValueOnce(undefined);

    const result = await recalculatePurchaseOrderReceiptStatusInternal(
      db,
      { purchaseOrderId: "missing-po" },
      commandCtx,
      mockInventoryQueries(),
    );

    expectErr(result, PurchaseOrderNotFoundError);
  });
});
