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

describe("getNotificationTemplate", () => {
  it("returns NotificationTemplate when found by id", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([{ ...baseTemplate }]);

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

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.template?.id).toBe(baseTemplate.id);
    }
  });

  it("returns NotificationTemplate when found by (eventType, channelId, locale) natural key", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([{ ...baseTemplate }]);

    const result = await run(mock.db, {
      eventType: "PO_ISSUED",
      channelId: "channel-1",
      locale: "en-US",
    });

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.template?.eventType).toBe("PO_ISSUED");
    }
  });

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

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

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

  it("returns null when the natural-key triple has no matching row (no fallback to default locale)", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([]);

    const result = await run(mock.db, {
      eventType: "PO_ISSUED",
      channelId: "channel-1",
      locale: "ja-JP",
    });

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

  it("returns the row with htmlBody populated for EMAIL templates that declare it", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([{ ...baseEmailTemplate }]);

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

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.template?.htmlBody).toBe(baseEmailTemplate.htmlBody);
    }
  });

  it("returns the row with htmlBody undefined / null for IN_APP templates that do not declare it", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([{ ...baseTemplate }]);

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

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.template?.htmlBody).toBeNull();
    }
  });

  it("returns the declared variableSchema on the row", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    mock.enqueueResults([{ ...baseTemplate }]);

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

    expect(result.ok).toBe(true);
    if (result.ok) {
      expect(result.value.template?.variableSchema).toBe(baseTemplate.variableSchema);
    }
  });
});
