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

describe("getLot", () => {
  it("returns lot when found by id", async () => {
    const { db, spies } = createMockDb<DB>();
    spies.select.mockReturnValueOnce(baseActiveLot);
    spies.select.mockReturnValueOnce([baseLotStockLevel]);

    const result = await run(db, { id: "lot-1" });
    const { lot } = expectOk<{ lot: unknown }>(result as never);

    expect(lot).not.toBeNull();
    expect(lot).toMatchObject({ id: "lot-1" });
  });

  it("returns lot when found by lotNumber and itemId", async () => {
    const { db, spies } = createMockDb<DB>();
    spies.select.mockReturnValueOnce(baseActiveLot);
    spies.select.mockReturnValueOnce([baseLotStockLevel]);

    const result = await run(db, { lotNumber: "LOT-001", itemId: "item-1" });
    const { lot } = expectOk<{ lot: unknown }>(result as never);

    expect(lot).not.toBeNull();
    expect(lot).toMatchObject({ id: "lot-1", lotNumber: "LOT-001" });
  });

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

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

    expect(lot).toBeNull();
    expect(lotStockLevels).toEqual([]);
  });

  it("includes lot stock levels across locations", async () => {
    const { db, spies } = createMockDb<DB>();
    spies.select.mockReturnValueOnce(baseActiveLot);
    spies.select.mockReturnValueOnce([baseLotStockLevel]);

    const result = await run(db, { id: "lot-1" });
    const { lotStockLevels } = expectOk<{ lotStockLevels: unknown[] }>(result as never);

    expect(lotStockLevels).toHaveLength(1);
    expect(lotStockLevels[0]).toMatchObject({
      lotId: "lot-1",
      storageLocationId: "location-1",
      onHand: 50,
    });
  });
});
