(function () {
  const DEFAULT_DURATION = 6200;
  const VARIANTS = ["info", "warning", "error"];
  const GENERIC_ERROR_MESSAGE = "Something went wrong on this page. Please try again in a moment.";

  window.Warpbox = window.Warpbox || {};
  let lastGlobalErrorAt = 0;

  function ensureRegion() {
    let region = document.querySelector("[data-warpbox-popups]");
    if (region) {
      return region;
    }
    region = document.createElement("div");
    region.className = "warpbox-popups";
    region.setAttribute("data-warpbox-popups", "");
    region.setAttribute("aria-live", "polite");
    region.setAttribute("aria-atomic", "false");
    document.body.append(region);
    return region;
  }

  function normalizeOptions(options, message) {
    if (typeof options === "string") {
      options = { message: options };
    } else {
      options = options || {};
    }
    if (message) {
      options.message = message;
    }
    const variant = VARIANTS.includes(options.variant) ? options.variant : "info";
    return {
      variant,
      title: options.title || defaultTitle(variant),
      message: options.message || "",
      duration: Number.isFinite(options.duration) ? options.duration : DEFAULT_DURATION,
      actions: Array.isArray(options.actions) ? options.actions : [],
    };
  }

  function defaultTitle(variant) {
    if (variant === "error") {
      return "Error";
    }
    if (variant === "warning") {
      return "Warning";
    }
    return "Info";
  }

  function notify(options, message) {
    const config = normalizeOptions(options, message);
    const region = ensureRegion();
    const popup = document.createElement("section");
    popup.className = "warpbox-popup warpbox-popup-" + config.variant;
    popup.setAttribute("role", config.variant === "error" ? "alert" : "status");

    const chrome = document.createElement("div");
    chrome.className = "warpbox-popup-chrome";

    const icon = document.createElement("span");
    icon.className = "warpbox-popup-icon";
    icon.setAttribute("aria-hidden", "true");
    icon.textContent = config.variant === "error" ? "!" : config.variant === "warning" ? "?" : "i";

    const body = document.createElement("div");
    body.className = "warpbox-popup-body";

    const title = document.createElement("strong");
    title.className = "warpbox-popup-title";
    title.textContent = config.title;

    const text = document.createElement("p");
    text.className = "warpbox-popup-message";
    text.textContent = config.message;

    body.append(title, text);

    const close = document.createElement("button");
    close.type = "button";
    close.className = "warpbox-popup-close";
    close.setAttribute("aria-label", "Dismiss notification");
    close.textContent = "x";
    close.addEventListener("click", () => dismiss(popup));

    chrome.append(icon, body, close);
    popup.append(chrome);

    if (config.actions.length > 0) {
      const actions = document.createElement("div");
      actions.className = "warpbox-popup-actions";
      config.actions.forEach((action) => {
        const button = document.createElement("button");
        button.type = "button";
        button.className = "button " + (action.kind === "primary" ? "button-primary" : "button-outline");
        button.textContent = action.label || "Action";
        button.addEventListener("click", () => {
          if (typeof action.onClick === "function") {
            action.onClick();
          }
          if (action.dismiss !== false) {
            dismiss(popup);
          }
        });
        actions.append(button);
      });
      popup.append(actions);
    }

    region.append(popup);
    window.requestAnimationFrame(() => popup.classList.add("is-visible"));

    let timer = null;
    if (config.duration > 0) {
      timer = window.setTimeout(() => dismiss(popup), config.duration);
    }

    return {
      element: popup,
      close: function closePopup() {
        if (timer) {
          window.clearTimeout(timer);
        }
        dismiss(popup);
      },
    };
  }

  function dismiss(popup) {
    if (!popup || popup.dataset.closing === "true") {
      return;
    }
    popup.dataset.closing = "true";
    popup.classList.remove("is-visible");
    window.setTimeout(() => popup.remove(), 180);
  }

  window.Warpbox.notify = notify;
  window.Warpbox.info = function info(message, options) {
    return notify({ ...(options || {}), variant: "info", message });
  };
  window.Warpbox.warning = function warning(message, options) {
    return notify({ ...(options || {}), variant: "warning", message });
  };
  window.Warpbox.error = function error(message, options) {
    return notify({ ...(options || {}), variant: "error", message });
  };

  function showGlobalError() {
    const now = Date.now();
    if (now - lastGlobalErrorAt < 2500) {
      return;
    }
    lastGlobalErrorAt = now;
    notify({
      variant: "error",
      title: "Page error",
      message: GENERIC_ERROR_MESSAGE,
      duration: 9000,
    });
  }

  window.addEventListener("error", function (event) {
    if (event && event.target && event.target !== window) {
      return;
    }
    showGlobalError();
  });

  window.addEventListener("unhandledrejection", function () {
    showGlobalError();
  });
})();
