/**
 * Toast-уведомления зоотех-страниц (нижний pill-toast, стиль Яндекс Музыки).
 */
(function (global) {
  const HOST_ID = "wespZtToastHost";
  const DEFAULT_DURATION_MS = 4000;
  const EXIT_MS = 220;

  const UM = () => global.WespUserMessages || {};
  const userFacingMessage = (message, fallback) => {
    const api = UM();
    if (typeof api.userFacingMessage === "function") {
      return api.userFacingMessage(message, fallback);
    }
    const text = message == null ? "" : String(message).trim();
    return text || fallback || "Не удалось выполнить операцию. Попробуйте ещё раз.";
  };

  let hostEl = null;
  let activeToast = null;
  let dismissTimer = null;

  function ensureHost() {
    if (hostEl && hostEl.isConnected) return hostEl;
    hostEl = document.getElementById(HOST_ID);
    if (!hostEl) {
      hostEl = document.createElement("div");
      hostEl.id = HOST_ID;
      hostEl.className = "wesp-zt-toast-host";
      hostEl.setAttribute("aria-live", "polite");
      hostEl.setAttribute("aria-atomic", "true");
      document.body.appendChild(hostEl);
    }
    return hostEl;
  }

  function clearDismissTimer() {
    if (dismissTimer) {
      clearTimeout(dismissTimer);
      dismissTimer = null;
    }
  }

  function normalizeType(type) {
    if (type === "error" || type === "warning") return type;
    return "success";
  }

  function escapeHtml(value) {
    return String(value)
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;");
  }

  function normalizeDisplayMessage(message) {
    if (message && typeof message === "object") {
      if (Array.isArray(message.parts)) return message;
      if (message.text != null) message = message.text;
    }
    const text = message == null ? "" : String(message).trim();
    if (/^Сохранено\b/i.test(text)) {
      return "Сохранено";
    }
    return text;
  }

  function renderMessageContent(message, opts) {
    if (message && typeof message === "object") {
      if (Array.isArray(message.parts)) {
        return message.parts
          .map((part) => {
            const text = escapeHtml(part && part.text != null ? part.text : "");
            return part && part.bold ? `<strong>${text}</strong>` : text;
          })
          .join("");
      }
      if (message.text != null) {
        return escapeHtml(message.text);
      }
    }

    const text = message == null ? "" : String(message);
    if (opts && Array.isArray(opts.parts)) {
      return opts.parts
        .map((part) => {
          const chunk = escapeHtml(part && part.text != null ? part.text : "");
          return part && part.bold ? `<strong>${chunk}</strong>` : chunk;
        })
        .join("");
    }
    return escapeHtml(text);
  }

  function removeToast(toastEl, immediate) {
    if (!toastEl || !toastEl.isConnected) return Promise.resolve();
    clearDismissTimer();
    if (immediate) {
      toastEl.remove();
      if (activeToast === toastEl) activeToast = null;
      return Promise.resolve();
    }

    return new Promise((resolve) => {
      toastEl.classList.add("is-exiting");
      const onEnd = () => {
        toastEl.removeEventListener("animationend", onEnd);
        toastEl.remove();
        if (activeToast === toastEl) activeToast = null;
        resolve();
      };
      toastEl.addEventListener("animationend", onEnd);
      setTimeout(onEnd, EXIT_MS + 40);
    });
  }

  function dismissAll() {
    clearDismissTimer();
    if (!activeToast) return;
    const toast = activeToast;
    activeToast = null;
    return removeToast(toast, false);
  }

  function plainTextFromMessage(message) {
    const api = UM();
    if (typeof api.plainText === "function") return api.plainText(message);
    if (message && typeof message === "object") {
      if (message instanceof Error) return "";
      if (Array.isArray(message.parts)) {
        return message.parts.map((p) => (p && p.text != null ? String(p.text) : "")).join("");
      }
      if (message.text != null) return String(message.text);
    }
    return message == null ? "" : String(message);
  }

  function persistNotification(type, message, opts) {
    if (opts && opts.skipRecord) return;
    const plain = plainTextFromMessage(
      message && typeof message === "object" && Array.isArray(message.parts)
        ? message
        : normalizeDisplayMessage(message)
    );
    if (!plain.trim() && !(opts && opts.record)) return;

    const builder = global.WespZootechNotificationMessages;
    const payload = builder
      ? builder.buildNotificationRecord(type, plain, opts)
      : {
          title: plain.slice(0, 200) || "Уведомление",
          detail: plain,
          kind: type,
          category: "general",
          page: "general",
        };

    fetch("/api/notifications", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    })
      .then(() => {
        global.WespZootechNotificationCenter?.refreshBadge?.();
      })
      .catch(() => {
        /* fire-and-forget */
      });
  }

  function show(type, message, opts) {
    const normalizedType = normalizeType(type);
    const duration =
      opts && Number.isFinite(opts.duration) ? opts.duration : DEFAULT_DURATION_MS;
    const displayMessage =
      message && typeof message === "object" && Array.isArray(message.parts)
        ? message
        : normalizeDisplayMessage(message);
    const html = renderMessageContent(displayMessage, opts);
    const plainText =
      displayMessage && typeof displayMessage === "object"
        ? ""
        : String(displayMessage || "");
    const isMultiline = plainText.length > 42 || /\n/.test(plainText);

    const run = async () => {
      if (activeToast) {
        await removeToast(activeToast, false);
      }

      const root = ensureHost();
      const toast = document.createElement("div");
      toast.className = `wesp-zt-toast wesp-zt-toast--${normalizedType}${
        isMultiline ? " wesp-zt-toast--multiline" : ""
      }`;
      toast.setAttribute("role", "status");

      const accent = document.createElement("span");
      accent.className = "wesp-zt-toast__accent";
      accent.setAttribute("aria-hidden", "true");

      const messageEl = document.createElement("p");
      messageEl.className = "wesp-zt-toast__message";
      messageEl.innerHTML = html;

      const closeBtn = document.createElement("button");
      closeBtn.type = "button";
      closeBtn.className = "wesp-zt-toast__close";
      closeBtn.setAttribute("aria-label", "Закрыть уведомление");
      closeBtn.textContent = "×";
      closeBtn.addEventListener("click", () => {
        dismissAll();
      });

      toast.append(accent, messageEl, closeBtn);
      root.appendChild(toast);
      activeToast = toast;

      if (duration > 0) {
        dismissTimer = setTimeout(() => {
          dismissAll();
        }, duration);
      }
    };

    persistNotification(normalizedType, displayMessage, opts);
    run();
  }

  function success(message, opts) {
    show("success", message, opts);
  }

  function error(message, opts) {
    const safe = userFacingMessage(message, opts && opts.fallback);
    show("error", safe, opts);
  }

  function warning(message, opts) {
    const safe = userFacingMessage(message, opts && opts.fallback);
    show("warning", safe, opts);
  }

  function open(payload) {
    const data = payload && typeof payload === "object" ? payload : {};
    show(data.type || "success", data.message, data);
  }

  function createAdapter() {
    return {
      success,
      error,
      warning,
      open,
      dismissAll,
    };
  }

  global.WespZootechNotify = {
    success,
    error,
    warning,
    open,
    dismissAll,
    createAdapter,
    userFacingMessage,
    messageFromResponseBody: (body, fallback) => {
      const api = UM();
      if (typeof api.messageFromResponseBody === "function") {
        return api.messageFromResponseBody(body, fallback);
      }
      return userFacingMessage(null, fallback);
    },
    isTechnicalMessage: (message) => {
      const api = UM();
      if (typeof api.isTechnicalMessage === "function") return api.isTechnicalMessage(message);
      return false;
    },
    DEFAULT_ERROR_MESSAGE: UM().DEFAULT_ERROR_MESSAGE || "Не удалось выполнить операцию. Попробуйте ещё раз.",
    get instance() {
      return createAdapter();
    },
  };
})(typeof window !== "undefined" ? window : globalThis);
