import { Notification } from "../data/entities.js";
import { NOTIFICATION_EVENTS } from "../lib/events.js";
import { DEFAULT_NOTIFICATION_DELIVERY_CONFIG, resolveNotificationDeliveryConfig, resolveNotificationPanelUrl } from "../lib/deliveryConfig.js";
import { getNotificationDeliveryStrategies } from "../lib/deliveryStrategies.js";
import { sendEmail } from "@open-mercato/shared/lib/email/send";
import NotificationEmail from "../emails/NotificationEmail.js";
import { loadDictionary } from "@open-mercato/shared/lib/i18n/server";
import { createFallbackTranslator } from "@open-mercato/shared/lib/i18n/translate";
import { defaultLocale } from "@open-mercato/shared/lib/i18n/config";
import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
import { User } from "../../auth/data/entities.js";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("notifications").child({ component: "deliver" });
const metadata = {
  event: NOTIFICATION_EVENTS.CREATED,
  persistent: true,
  id: "notifications:deliver"
};
function debug(message, ...details) {
  logger.debug(message, details.length ? { details } : void 0);
}
const buildPanelLink = (panelUrl, notificationId) => {
  if (panelUrl.startsWith("http://") || panelUrl.startsWith("https://")) {
    const url = new URL(panelUrl);
    url.searchParams.set("notificationId", notificationId);
    return url.toString();
  }
  const separator = panelUrl.includes("?") ? "&" : "?";
  return `${panelUrl}${separator}notificationId=${encodeURIComponent(notificationId)}`;
};
const resolveNotificationCopy = async (notification) => {
  const dict = await loadDictionary(defaultLocale);
  const t = createFallbackTranslator(dict);
  const title = notification.titleKey ? t(notification.titleKey, notification.title ?? notification.titleKey, notification.titleVariables ?? void 0) : notification.title;
  const body = notification.bodyKey ? t(notification.bodyKey, notification.body ?? notification.bodyKey ?? "", notification.bodyVariables ?? void 0) : notification.body ?? null;
  return { title, body, t };
};
const resolveRecipient = async (em, notification, encryptionService) => {
  const where = {
    id: notification.recipientUserId,
    tenantId: notification.tenantId,
    deletedAt: null
  };
  if (notification.organizationId) {
    where.organizationId = notification.organizationId;
  }
  const record = await findOneWithDecryption(
    em,
    User,
    where,
    void 0,
    {
      tenantId: notification.tenantId,
      organizationId: notification.organizationId ?? null,
      encryptionService: encryptionService ?? null
    }
  );
  if (!record) return null;
  return {
    email: typeof record.email === "string" ? record.email : null,
    name: typeof record.name === "string" ? record.name : null
  };
};
async function handle(payload, ctx) {
  debug("deliver notification event", payload);
  const deliveryConfig = await resolveNotificationDeliveryConfig(ctx, { defaultValue: DEFAULT_NOTIFICATION_DELIVERY_CONFIG });
  if (!deliveryConfig.strategies.email.enabled) {
    debug("email delivery disabled");
  }
  const em = ctx.resolve("em");
  const notification = await findOneWithDecryption(
    em,
    Notification,
    {
      id: payload.notificationId,
      tenantId: payload.tenantId,
      organizationId: payload.organizationId ?? null
    },
    void 0,
    {
      tenantId: payload.tenantId,
      organizationId: payload.organizationId ?? null,
      encryptionService: null
    }
  );
  if (!notification) {
    debug("notification not found", payload.notificationId);
    return;
  }
  let encryptionService = null;
  try {
    encryptionService = ctx.resolve("tenantEncryptionService");
  } catch {
    encryptionService = null;
  }
  try {
    const recipient = await resolveRecipient(em, notification, encryptionService) ?? { email: null, name: null };
    if (!recipient?.email) {
      debug("recipient has no email", notification.recipientUserId);
    }
    const { title, body, t } = await resolveNotificationCopy(notification);
    const panelUrl = resolveNotificationPanelUrl(deliveryConfig);
    if (!panelUrl) {
      debug("missing panelUrl; check appUrl/panelPath settings");
    }
    const panelLink = panelUrl ? buildPanelLink(panelUrl, notification.id) : null;
    const baseOrigin = panelUrl ? new URL(panelUrl).origin : null;
    const actionLinks = (notification.actionData?.actions ?? []).map((action) => {
      let href = action.href;
      if (href && notification.sourceEntityId) {
        href = href.replace("{sourceEntityId}", notification.sourceEntityId);
      }
      const fullHref = href && baseOrigin ? `${baseOrigin}${href}` : panelLink;
      if (!fullHref) return null;
      return {
        id: action.id,
        label: action.labelKey ? t(action.labelKey, action.label) : action.label,
        href: fullHref
      };
    }).filter((action) => action !== null);
    if (deliveryConfig.strategies.email.enabled && recipient?.email && panelLink) {
      const subjectPrefix = deliveryConfig.strategies.email.subjectPrefix?.trim();
      const subject = subjectPrefix ? `${subjectPrefix} ${title}` : title;
      const copy = {
        preview: t("notifications.delivery.email.preview", "New notification"),
        heading: t("notifications.delivery.email.heading", "You have a new notification"),
        bodyIntro: t("notifications.delivery.email.bodyIntro", "Review the notification details and take any required actions."),
        actionNotice: t("notifications.delivery.email.actionNotice", "Actions are available in Open Mercato and are read-only in this email."),
        openCta: t("notifications.delivery.email.openCta", "Open notification center"),
        footer: t("notifications.delivery.email.footer", "Open Mercato notifications")
      };
      try {
        debug("sending email", { recipientUserId: notification.recipientUserId });
        await sendEmail({
          to: recipient.email,
          subject,
          from: deliveryConfig.strategies.email.from,
          replyTo: deliveryConfig.strategies.email.replyTo,
          react: NotificationEmail({
            title,
            body,
            actions: actionLinks,
            panelUrl: panelLink,
            copy
          })
        });
      } catch (error) {
        logger.error("Email delivery failed", { err: error });
      }
    }
    const strategyConfigs = deliveryConfig.strategies.custom ?? {};
    const strategies = getNotificationDeliveryStrategies();
    for (const strategy of strategies) {
      const strategyConfig = strategyConfigs[strategy.id];
      const enabled = strategyConfig?.enabled ?? strategy.defaultEnabled ?? false;
      if (!enabled) {
        debug("custom delivery disabled", strategy.id);
        continue;
      }
      try {
        await strategy.deliver({
          notification,
          recipient,
          title,
          body,
          panelUrl,
          panelLink,
          actionLinks,
          deliveryConfig,
          config: strategyConfig ?? {},
          resolve: ctx.resolve,
          t
        });
      } catch (error) {
        logger.error("Delivery strategy failed", { strategyId: strategy.id, err: error });
      }
    }
  } catch (err) {
    logger.error("Failed to deliver notification", { notificationId: payload.notificationId, recipientUserId: notification.recipientUserId, err });
    throw err;
  }
  return;
}
export {
  handle as default,
  metadata
};
//# sourceMappingURL=deliver-notification.js.map
