import { createKyselyMock } from "@tailor-platform/sdk/vitest";
import { describe, expect, it } from "vitest";
import type { Namespace } from "../generated/kysely-tailordb";
import { baseActiveItem, baseDraftItem } from "../testing/fixtures";
import { run } from "./getItem";

describe("getItem", () => {
  describe("by id", () => {
    it("returns item when found", async () => {
      const mock = createKyselyMock<Namespace["main-db"]>();
      mock.enqueueResults([baseDraftItem]);

      const result = await run(mock.db, { id: "item-1" });

      expect(result.ok).toBe(true);
      if (result.ok) {
        expect(result.value.item).toEqual(baseDraftItem);
      }

      expect(mock.selects).toHaveLength(1);
      expect(mock.selects[0]?.parameters).toContain("item-1");
      expect(mock.selects[0]?.sql).toMatch(/"id"/);
    });

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

      const result = await run(mock.db, { id: "nonexistent" });

      expect(result.ok).toBe(true);
      if (result.ok) {
        expect(result.value.item).toBeNull();
      }

      expect(mock.selects).toHaveLength(1);
      expect(mock.selects[0]?.parameters).toContain("nonexistent");
      expect(mock.selects[0]?.sql).toMatch(/"id"/);
    });
  });

  describe("by sku", () => {
    it("returns item when found", async () => {
      const mock = createKyselyMock<Namespace["main-db"]>();
      mock.enqueueResults([baseDraftItem]);

      const result = await run(mock.db, { sku: "SKU-001" });

      expect(result.ok).toBe(true);
      if (result.ok) {
        expect(result.value.item).toEqual(baseDraftItem);
      }

      expect(mock.selects).toHaveLength(1);
      expect(mock.selects[0]?.parameters).toContain("SKU-001");
      expect(mock.selects[0]?.sql).toMatch(/"sku"/);
    });

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

      const result = await run(mock.db, { sku: "NONEXISTENT" });

      expect(result.ok).toBe(true);
      if (result.ok) {
        expect(result.value.item).toBeNull();
      }

      expect(mock.selects).toHaveLength(1);
      expect(mock.selects[0]?.parameters).toContain("NONEXISTENT");
      expect(mock.selects[0]?.sql).toMatch(/"sku"/);
    });
  });

  describe("by barcode", () => {
    it("returns item when found", async () => {
      const mock = createKyselyMock<Namespace["main-db"]>();
      mock.enqueueResults([baseActiveItem]);

      const result = await run(mock.db, { barcode: "BAR-002" });

      expect(result.ok).toBe(true);
      if (result.ok) {
        expect(result.value.item).toEqual(baseActiveItem);
      }

      expect(mock.selects).toHaveLength(1);
      expect(mock.selects[0]?.parameters).toContain("BAR-002");
      expect(mock.selects[0]?.sql).toMatch(/"barcode"/);
    });

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

      const result = await run(mock.db, { barcode: "NONEXISTENT" });

      expect(result.ok).toBe(true);
      if (result.ok) {
        expect(result.value.item).toBeNull();
      }

      expect(mock.selects).toHaveLength(1);
      expect(mock.selects[0]?.parameters).toContain("NONEXISTENT");
      expect(mock.selects[0]?.sql).toMatch(/"barcode"/);
    });
  });
});
