/* global React, ReactDOM */
// =============================================================================
// BWAY PROD — Sistema de notificaciones brand-aligned
// Reemplazo de alert(), confirm(), prompt() y todas las alertas nativas.
//
// API:
//   window.bwayNotify.toast(message, options?)   // toast simple
//   window.bwayNotify.success(message)           // toast verde
//   window.bwayNotify.error(message)             // toast rojo
//   window.bwayNotify.info(message)              // toast dorado
//   await window.bwayNotify.confirm(message)     // modal de sí/no, devuelve bool
//   await window.bwayNotify.prompt(label, opts?) // modal con input, devuelve string|null
//   await window.bwayNotify.alert(message)       // modal de alerta con OK
// =============================================================================

(function () {
  const { useState, useEffect, useRef } = React;
  const e = React.createElement;

  // -----------------------------------------------------------
  // ToastContainer — renderiza los toasts apilados
  // -----------------------------------------------------------
  let toastId = 0;
  let pushToast = null;     // será seteado por el componente al montarse
  let pushModal = null;

  function ToastContainer() {
    const [toasts, setToasts] = useState([]);
    useEffect(() => {
      pushToast = (toast) => {
        const id = ++toastId;
        setToasts((cur) => [...cur, { ...toast, id }]);
        const ttl = toast.duration ?? 4500;
        if (ttl > 0) {
          setTimeout(() => {
            setToasts((cur) => cur.filter((t) => t.id !== id));
          }, ttl);
        }
        return id;
      };
      return () => { pushToast = null; };
    }, []);
    function dismiss(id) {
      setToasts((cur) => cur.filter((t) => t.id !== id));
    }
    return e("div", { className: "bn-toast-container", "aria-live": "polite" },
      toasts.map((t) =>
        e("div", {
          key: t.id,
          className: "bn-toast bn-toast-" + (t.kind || "info"),
          onClick: () => dismiss(t.id),
          role: "alert"
        },
          e("span", { className: "bn-toast-icon" },
            t.kind === "success" ? "✓" :
            t.kind === "error"   ? "✕" :
            t.kind === "warning" ? "⚠" :
            "✦"
          ),
          e("span", { className: "bn-toast-msg" }, t.message),
          e("button", { className: "bn-toast-x", onClick: (ev) => { ev.stopPropagation(); dismiss(t.id); } }, "×")
        )
      )
    );
  }

  // -----------------------------------------------------------
  // ModalContainer — alert / confirm / prompt
  // -----------------------------------------------------------
  function ModalContainer() {
    const [modal, setModal] = useState(null);
    const inputRef = useRef(null);

    useEffect(() => {
      pushModal = (m) => setModal(m);
      return () => { pushModal = null; };
    }, []);

    useEffect(() => {
      if (modal?.kind === "prompt" && inputRef.current) {
        setTimeout(() => inputRef.current?.focus(), 100);
      }
      function onKey(ev) {
        if (!modal) return;
        if (ev.key === "Escape") close(modal.kind === "confirm" ? false : null);
        if (ev.key === "Enter" && modal.kind !== "prompt") {
          ev.preventDefault();
          close(modal.kind === "confirm" ? true : true);
        }
      }
      window.addEventListener("keydown", onKey);
      return () => window.removeEventListener("keydown", onKey);
    }, [modal]);

    function close(result) {
      if (modal?.resolve) modal.resolve(result);
      setModal(null);
    }

    if (!modal) return null;

    function onBackdropClick(ev) {
      if (ev.target === ev.currentTarget) {
        close(modal.kind === "confirm" ? false : null);
      }
    }

    function handleSubmit(ev) {
      if (ev) ev.preventDefault();
      if (modal.kind === "prompt") {
        const v = inputRef.current?.value || "";
        close(v);
      } else {
        close(true);
      }
    }

    const isDanger = modal.danger === true;
    return e("div", { className: "bn-modal-backdrop", onClick: onBackdropClick },
      e("div", { className: "bn-modal" + (isDanger ? " is-danger" : ""), role: "dialog", "aria-modal": "true" },
        e("div", { className: "bn-modal-head" },
          modal.kicker ? e("span", { className: "bn-modal-kicker" }, modal.kicker) :
            e("span", { className: "bn-modal-kicker" },
              modal.kind === "confirm" ? "/ CONFIRMAR" :
              modal.kind === "prompt"  ? "/ INGRESAR" :
              "/ AVISO"),
          modal.title ? e("h3", { className: "bn-modal-title" }, modal.title) : null
        ),
        e("p", { className: "bn-modal-msg" }, modal.message),
        modal.kind === "prompt" ? e("form", { onSubmit: handleSubmit },
          e("input", {
            ref: inputRef,
            type: modal.inputType || "text",
            className: "bn-modal-input",
            defaultValue: modal.defaultValue || "",
            placeholder: modal.placeholder || ""
          })
        ) : null,
        e("div", { className: "bn-modal-actions" },
          modal.kind !== "alert" ? e("button", {
            className: "bn-modal-btn bn-modal-btn-ghost",
            onClick: () => close(modal.kind === "confirm" ? false : null),
            type: "button"
          }, modal.cancelLabel || "Cancelar") : null,
          e("button", {
            className: "bn-modal-btn " + (isDanger ? "bn-modal-btn-danger" : "bn-modal-btn-gold"),
            onClick: () => handleSubmit(),
            type: "button"
          }, modal.confirmLabel || (modal.kind === "confirm" ? "Confirmar" : modal.kind === "prompt" ? "Aceptar" : "OK"))
        )
      )
    );
  }

  // -----------------------------------------------------------
  // Root — combina toast + modal containers en un único portal
  // -----------------------------------------------------------
  function NotifyRoot() {
    return e(React.Fragment, null,
      e(ToastContainer),
      e(ModalContainer)
    );
  }

  // -----------------------------------------------------------
  // Mount el container en el body
  // -----------------------------------------------------------
  function mountNotify() {
    if (document.getElementById("bway-notify-root")) return;
    const el = document.createElement("div");
    el.id = "bway-notify-root";
    document.body.appendChild(el);
    const root = (ReactDOM.createRoot ? ReactDOM.createRoot(el) : null);
    if (root) {
      root.render(e(NotifyRoot));
    } else {
      // Fallback ReactDOM legacy
      ReactDOM.render(e(NotifyRoot), el);
    }
  }

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", mountNotify);
  } else {
    mountNotify();
  }

  // -----------------------------------------------------------
  // Override de alert() nativo → bwayNotify (es void, safe)
  // confirm() y prompt() son sync y los call sites los esperan así,
  // por eso NO los overrideamos globalmente. Las usages migradas
  // usan await window.bwayNotify.confirm() / .prompt()
  // -----------------------------------------------------------
  const nativeAlert = window.alert.bind(window);
  window.alert = function (msg) {
    window.bwayNotify.error(String(msg ?? ""));
  };

  // -----------------------------------------------------------
  // Public API
  // -----------------------------------------------------------
  window.bwayNotify = {
    toast(message, options = {}) {
      if (!pushToast) {
        // Retry shortly
        setTimeout(() => pushToast && pushToast({ message, ...options }), 200);
        return null;
      }
      return pushToast({ message, ...options });
    },
    success(message, options = {}) { return this.toast(message, { ...options, kind: "success" }); },
    error(message, options = {})   { return this.toast(message, { ...options, kind: "error", duration: 7000 }); },
    info(message, options = {})    { return this.toast(message, { ...options, kind: "info" }); },
    warning(message, options = {}) { return this.toast(message, { ...options, kind: "warning" }); },

    confirm(message, options = {}) {
      return new Promise((resolve) => {
        const open = () => pushModal?.({ kind: "confirm", message, ...options, resolve });
        if (pushModal) open();
        else setTimeout(open, 200);
      });
    },
    prompt(message, options = {}) {
      return new Promise((resolve) => {
        const open = () => pushModal?.({ kind: "prompt", message, ...options, resolve });
        if (pushModal) open();
        else setTimeout(open, 200);
      });
    },
    alert(message, options = {}) {
      return new Promise((resolve) => {
        const open = () => pushModal?.({ kind: "alert", message, ...options, resolve });
        if (pushModal) open();
        else setTimeout(open, 200);
      });
    }
  };
})();
