// This is a separate file since the other utils import `config.js`, which depends on `window`
// and cannot be used in the service worker

import emojisMapped from "./emojisMapped";
import { ACTION_HTTP, ACTION_VIEW } from "./actions";

const toEmojis = (tags) => {
  if (!tags) return [];
  return tags.filter((tag) => tag in emojisMapped).map((tag) => emojisMapped[tag]);
};

export const formatTitle = (m) => {
  const emojiList = toEmojis(m.tags);
  if (emojiList.length > 0) {
    return `${emojiList.join(" ")} ${m.title}`;
  }
  return m.title;
};

const formatTitleWithDefault = (m, fallback) => {
  if (m.title) {
    return formatTitle(m);
  }
  return fallback;
};

export const formatMessage = (m) => {
  if (m.title) {
    return m.message || "";
  }
  const emojiList = toEmojis(m.tags);
  if (emojiList.length > 0) {
    return `${emojiList.join(" ")} ${m.message || ""}`;
  }
  return m.message || "";
};

export const imageRegex = /\.(png|jpe?g|gif|webp)$/i;
export const isImage = (attachment) => {
  if (!attachment) return false;

  // if there's a type, only take that into account
  if (attachment.type) {
    return attachment.type.startsWith("image/");
  }

  // otherwise, check the extension
  return attachment.name?.match(imageRegex) || attachment.url?.match(imageRegex);
};

export const icon = "/static/images/ntfy.png";
export const badge = "/static/images/mask-icon.svg";

/**
 * Computes a unique notification tag scoped by baseUrl, topic, and sequence ID.
 * This ensures notifications from different topics with the same sequence ID don't collide.
 */
export const notificationTag = (baseUrl, topic, sequenceId) => `${baseUrl}/${topic}/${sequenceId}`;

export const toNotificationParams = ({ message, defaultTitle, topicRoute, baseUrl, topic }) => {
  const image = isImage(message.attachment) ? message.attachment.url : undefined;
  const sequenceId = message.sequence_id || message.id;
  const tag = notificationTag(baseUrl, topic, sequenceId);
  const subscriptionId = `${baseUrl}/${topic}`;

  // https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API
  return [
    formatTitleWithDefault(message, defaultTitle),
    {
      body: formatMessage(message),
      badge,
      icon,
      image,
      timestamp: message.time * 1000,
      tag, // Scoped by baseUrl/topic/sequenceId to avoid cross-topic collisions
      renotify: true,
      silent: false,
      // This is used by the notification onclick event
      data: {
        subscriptionId,
        message,
        topicRoute,
      },
      actions: message.actions
        ?.filter(({ action }) => action === ACTION_VIEW || action === ACTION_HTTP)
        .map(({ label }) => ({
          action: label,
          title: label,
        })),
    },
  ];
};

export const messageWithSequenceId = (message) => {
  if (message.sequenceId) {
    return message;
  }
  return { ...message, sequenceId: message.sequence_id || message.id };
};
