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

describe("listNotificationCategories", () => {
  it("returns every seeded NotificationCategory", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([{ ...baseTransactionalCategory }, { ...baseOptionalCategory }]);

    const result = await run(mock.db, {});

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.items).toHaveLength(2);
    }
  });

  it("returns each row with optOutAllowed = true for optional categories (announcements, rfq-updates, etc.)", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([{ ...baseOptionalCategory }]);

    const result = await run(mock.db, {});

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.items[0]?.optOutAllowed).toBe(true);
    }
  });

  it("returns each row with optOutAllowed = false for transactional categories (invoice-updates, supplier-lifecycle, etc.)", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([{ ...baseTransactionalCategory }]);

    const result = await run(mock.db, {});

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.items[0]?.optOutAllowed).toBe(false);
    }
  });

  it("returns an empty list when the catalog has not been seeded", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([]);

    const result = await run(mock.db, {});

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.items).toEqual([]);
    }
  });

  it("honors limit/offset pagination and reports hasNextPage when more rows remain", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    // limit + 1 rows returned -> hasNextPage = true
    mock.enqueueResults([{ ...baseTransactionalCategory }, { ...baseOptionalCategory }]);

    const result = await run(mock.db, { limit: 1, offset: 0 });

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.items).toHaveLength(1);
      expect(result.value.hasNextPage).toBe(true);
    }
  });
});
