﻿// Pau Polaino — runtime de publicación
// · ResponsivePage: elige Desktop (1440) o Móvil (390) según el ancho y escala
//   con `zoom` para llenar la pantalla de forma fluida (reflow nativo, scroll suave).
// · Enrutado global de CTAs por texto (todo "Reservar…" → contacto).

const PP_BREAKPOINT = 820;   // < 820px → móvil
const PP_DESKTOP_W = 1440;
const PP_MOBILE_W = 390;
const PP_MAX_ZOOM = 1.35;    // tope de ampliación en monitores grandes

function ppViewportWidth() {
  return document.documentElement.clientWidth || window.innerWidth;
}

function ResponsivePage({ desktop: Desktop, mobile: Mobile, bg }) {
  const [vw, setVw] = React.useState(ppViewportWidth);

  React.useEffect(() => {
    let raf = 0;
    const onResize = () => {
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(() => setVw(ppViewportWidth()));
    };
    window.addEventListener("resize", onResize);
    window.addEventListener("orientationchange", onResize);
    return () => {
      window.removeEventListener("resize", onResize);
      window.removeEventListener("orientationchange", onResize);
    };
  }, []);

  const isMobile = vw < PP_BREAKPOINT;
  const base = isMobile ? PP_MOBILE_W : PP_DESKTOP_W;
  let zoom = vw / base;
  if (!isMobile && zoom > PP_MAX_ZOOM) zoom = PP_MAX_ZOOM;

  const Comp = isMobile ? Mobile : Desktop;

  // Avisar a la página (p.ej. contacto) cada vez que cambia el componente montado
  React.useEffect(() => {
    window.dispatchEvent(new CustomEvent("pp:mounted", { detail: { isMobile } }));
    ppHideSplash();
  }, [isMobile]);

  return (
    <div style={{ background: bg || "var(--cream)", minHeight: "100vh" }}>
      <div style={{ zoom: zoom, display: "flex", justifyContent: "center" }}>
        <div style={{ width: base }}>
          <Comp />
        </div>
      </div>
    </div>
  );
}

function ppHideSplash() {
  const s = document.getElementById("pp-splash");
  if (s) requestAnimationFrame(() => s.classList.add("hide"));
}

/* Monta una página: pasa los componentes Desktop y Móvil */
function ppRender(Desktop, Mobile, opts) {
  opts = opts || {};
  ReactDOM.createRoot(document.getElementById("root")).render(
    <ResponsivePage desktop={Desktop} mobile={Mobile} bg={opts.bg} />
  );
}

/* ---------- Enrutado global de CTAs (botones sin <a> propio) ---------- */
(function () {
  document.addEventListener("click", function (e) {
    // Si el clic está dentro de un <a> real, dejar que navegue solo
    if (e.target.closest("a")) return;
    const btn = e.target.closest("button");
    if (!btn) return;
    const txt = (btn.textContent || "").trim().toLowerCase();

    if (/reservar|llamada informativa|^agenda/.test(txt)) {
      e.preventDefault();
      location.href = "/contacto/";
    } else if (txt === "volver a inicio" || txt === "inicio") {
      e.preventDefault();
      location.href = "/";
    } else if (/quiero el ebook/.test(txt)) {
      // Newsletter sin backend conectado: evitar recarga del formulario
      e.preventDefault();
    }
  });
})();

/* ---------- Anclas en página (#servicios, #sobre-pau, #reservar, #planes…) ----------
   El contenido lo monta React tras compilar Babel, así que el salto nativo al ancla
   falla (el elemento aún no existe). Manejamos los anclas a mano:
   · clic en la misma página → scroll suave sin recargar
   · al cargar/montar con #hash en la URL → reintenta el scroll hasta que el destino exista */
(function () {
  function scrollToHash(hash, smooth) {
    if (!hash || hash === "#") return false;
    var id = decodeURIComponent(hash.slice(1));
    var el = document.getElementById(id);
    if (!el) return false;
    var startY = window.scrollY;
    var gap = parseInt(el.getAttribute("data-scroll-gap") || "12", 10);
    if (isNaN(gap)) gap = 12;
    var top = el.getBoundingClientRect().top + window.scrollY - gap;
    window.scrollTo({ top: top < 0 ? 0 : top, behavior: smooth ? "smooth" : "auto" });
    // Fallback para contextos embebidos donde el scroll de ventana está fijado:
    // si no se movió, usar scrollIntoView sobre el contenedor real.
    setTimeout(function () {
      if (Math.abs(window.scrollY - startY) < 4 && el.getBoundingClientRect().top > 8) {
        try { el.scrollIntoView({ behavior: smooth ? "smooth" : "auto", block: "start" }); }
        catch (_) { el.scrollIntoView(); }
      }
    }, 140);
    return true;
  }

  // Clics en anclas de la misma página → sin recarga
  document.addEventListener("click", function (e) {
    var a = e.target.closest("a[href]");
    if (!a) return;
    var raw = a.getAttribute("href");
    if (!raw || raw.indexOf("#") === -1) return;
    var url;
    try { url = new URL(a.href, location.href); } catch (_) { return; }
    if (url.pathname === location.pathname && url.hash) {
      var el = document.getElementById(decodeURIComponent(url.hash.slice(1)));
      if (el) {
        e.preventDefault();
        history.pushState(null, "", url.hash);
        scrollToHash(url.hash, true);
      }
    }
  });

  // #hash inicial (al venir de otra página) → reintenta tras el montaje de React
  function handleInitialHash() {
    if (!location.hash) return;
    var tries = 0;
    var iv = setInterval(function () {
      if (scrollToHash(location.hash, false) || ++tries > 50) clearInterval(iv);
    }, 120);
  }
  window.addEventListener("pp:mounted", function () { setTimeout(handleInitialHash, 60); });
  window.addEventListener("load", function () { setTimeout(handleInitialHash, 200); });
  window.addEventListener("hashchange", function () { scrollToHash(location.hash, true); });

  window.ppScrollToHash = scrollToHash;
})();

/* ---------- Scroll-reveal para tarjetas .pp-reveal ---------- */
(function () {
  if (!("IntersectionObserver" in window)) return;
  const io = new IntersectionObserver(function (entries) {
    entries.forEach(function (en) {
      if (en.isIntersecting) en.target.classList.add("pp-in");
      else en.target.classList.remove("pp-in");
    });
  }, { rootMargin: "-18% 0px -18% 0px", threshold: 0 });
  function scan() {
    document.querySelectorAll(".pp-reveal:not([data-reveal-bound])").forEach(function (el) {
      el.setAttribute("data-reveal-bound", "1");
      io.observe(el);
    });
  }
  setInterval(scan, 700);
  window.addEventListener("load", scan);
})();

Object.assign(window, { ResponsivePage, ppRender, ppHideSplash });

