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 "./getNotificationChannel";

describe("getNotificationChannel", () => {
  it("returns NotificationChannel when found by channelId", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([{ ...baseInAppChannel }]);

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

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.channel).not.toBeNull();
      expect(result.value.channel?.channelId).toBe("IN_APP");
    }
  });

  it("returns null when channelId does not exist in the registry", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([]);

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

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

  it("returns the channel with enabled = false (does not filter by enabled flag)", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([{ ...baseDisabledEmailChannel }]);

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

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.channel?.enabled).toBe(false);
    }
  });

  it("returns capability flags (supportsHtmlBody, supportsAttachments, supportsRichActions) on the result", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([{ ...baseEmailChannel }]);

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

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.channel?.capabilities.supportsHtmlBody).toBe(true);
      expect(result.value.channel?.capabilities.supportsAttachments).toBe(true);
      expect(result.value.channel?.capabilities.supportsRichActions).toBe(false);
    }
  });

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

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

      expect(result.ok).toBe(true);
      if (result.ok) {
        expect(result.value.channel?.channelId).toBe(channelId);
      }
    }
  });
});
