import { createKyselyMock } from "@tailor-platform/sdk/vitest";
import { describe, expect, it } from "vitest";
import type { Namespace } from "../generated/kysely-tailordb";
import { baseInAppChannel, baseEmailChannel, baseDisabledEmailChannel } from "../testing/fixtures";
import { run } from "./listNotificationChannels";

describe("listNotificationChannels", () => {
  it("returns every registered NotificationChannel when no filter is supplied", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([
      { ...baseInAppChannel },
      { ...baseEmailChannel },
      { ...baseDisabledEmailChannel },
    ]);

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

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

  it("returns only enabled = true channels when enabledOnly = true", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([
      { ...baseInAppChannel, enabled: true },
      { ...baseEmailChannel, enabled: true },
    ]);

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

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.items).toHaveLength(2);
      expect(result.value.items.every((c) => c.enabled)).toBe(true);
    }
  });

  it("returns disabled channels when enabledOnly is omitted or false", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([{ ...baseEmailChannel, enabled: true }, { ...baseDisabledEmailChannel }]);

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

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.items).toHaveLength(2);
      expect(result.value.items.some((c) => !c.enabled)).toBe(true);
    }
  });

  it("returns reserved channels (SMS, PUSH, SLACK, TEAMS) when they exist in the registry", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([
      { ...baseInAppChannel, channelId: "SMS", displayName: "SMS" },
      { ...baseInAppChannel, channelId: "PUSH", displayName: "Push" },
      { ...baseInAppChannel, channelId: "SLACK", displayName: "Slack" },
      { ...baseInAppChannel, channelId: "TEAMS", displayName: "Teams" },
    ]);

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

    expect(result.ok).toBe(true);
    if (result.ok) {
      const ids = result.value.items.map((c) => c.channelId);
      expect(ids).toEqual(expect.arrayContaining(["SMS", "PUSH", "SLACK", "TEAMS"]));
    }
  });

  it("returns an empty list when no channels match the filter", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([]);

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

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