/* global React, ReactDOM, AppCtx, Header, Footer, HomePage, CatalogPage, ProductPage, CartPage, PLANCHETTE_CURSOR, planchetteSvg */
const { createElement: a, useState: useStateApp, useEffect: useEffectApp, useCallback } = React;

/* ===== Planchette "poseída": tras 1 min de inactividad se desliza sola (efecto ouija) ===== */
const SPIRIT_IDLE_MS = 30000;
function SpiritPlanchette() {
  const [active, setActive] = useStateApp(false);
  const [pos, setPos] = useStateApp({ x: -200, y: -200 });

  /* detección de inactividad */
  useEffectApp(() => {
    let timer;
    const arm = () => { clearTimeout(timer); timer = setTimeout(() => setActive(true), SPIRIT_IDLE_MS); };
    const wake = () => { setActive(false); arm(); };
    const evs = ["mousemove", "mousedown", "keydown", "wheel", "touchstart"];
    evs.forEach(e => window.addEventListener(e, wake, { passive: true }));
    arm();
    return () => { clearTimeout(timer); evs.forEach(e => window.removeEventListener(e, wake)); };
  }, []);

  /* mientras está activa: se desliza a puntos al azar y oculta el cursor real */
  useEffectApp(() => {
    if (!active) { document.documentElement.style.cursor = PLANCHETTE_CURSOR; return; }
    document.documentElement.style.cursor = "none";
    const drift = () => {
      const w = window.innerWidth, h = window.innerHeight;
      setPos({ x: w * 0.16 + Math.random() * w * 0.68, y: h * 0.24 + Math.random() * h * 0.52 });
    };
    drift();
    const iv = setInterval(drift, 2600);
    return () => clearInterval(iv);
  }, [active]);

  return a("div", {
    "aria-hidden": "true",
    style: {
      position: "fixed", left: 0, top: 0, zIndex: 9998, pointerEvents: "none",
      transform: `translate3d(${pos.x}px, ${pos.y}px, 0)`,
      transition: "transform 2.4s cubic-bezier(.45,.06,.3,1), opacity .9s ease",
      opacity: active ? 0.97 : 0,
      filter: "drop-shadow(0 0 18px rgba(231,206,138,.55))",
      willChange: "transform"
    }
  }, a("div", { style: { transform: "translate(-50%,-50%)" }, dangerouslySetInnerHTML: { __html: planchetteSvg(66, 86) } }));
}

/* ===== Routing por URL (SPA con History API) + SEO por página ===== */
const SITE = "https://mictlanmex.com";
const LEGAL_PATHS = { terminos: "/terminos", privacidad: "/privacidad", faq: "/preguntas", envios: "/envios", cambios: "/cambios", tallas: "/tallas" };
const PATH_LEGAL = { "/terminos": "terminos", "/privacidad": "privacidad", "/preguntas": "faq", "/envios": "envios", "/cambios": "cambios", "/tallas": "tallas" };

function routeToPath(page, params) {
  params = params || {};
  if (page === "catalog") {
    if (params.favs) return "/favoritos";
    if (params.nuevo) return "/nuevo";
    if (params.cat) return "/tienda/" + params.cat;
    return "/tienda";
  }
  if (page === "product") return "/producto/" + (params.id || "");
  if (page === "cart") return "/carrito";
  if (LEGAL_PATHS[page]) return LEGAL_PATHS[page];
  return "/";
}
function pathToRoute(pathname) {
  var p = (pathname || "/").replace(/\/+$/, "") || "/";
  if (p === "/" || p === "") return { page: "home", params: {} };
  if (p === "/tienda") return { page: "catalog", params: {} };
  if (p === "/favoritos") return { page: "catalog", params: { favs: true } };
  if (p === "/nuevo") return { page: "catalog", params: { nuevo: true } };
  var mCat = p.match(/^\/tienda\/([^\/]+)$/);
  if (mCat) return { page: "catalog", params: { cat: decodeURIComponent(mCat[1]) } };
  var mProd = p.match(/^\/producto\/([^\/]+)$/);
  if (mProd) return { page: "product", params: { id: decodeURIComponent(mProd[1]) } };
  if (p === "/carrito") return { page: "cart", params: {} };
  if (PATH_LEGAL[p]) return { page: PATH_LEGAL[p], params: {} };
  return { page: "home", params: {} };
}
function absUrl(src) { return !src ? SITE + "/img/og-mictlan.jpg" : (/^https?:/i.test(src) ? src : SITE + "/" + String(src).replace(/^\//, "")); }
function clipTxt(s, n) { s = String(s || "").replace(/\s+/g, " ").trim(); return s.length > n ? s.slice(0, n - 1).trim() + "…" : s; }
function setMetaTag(attr, key, content) {
  var el = document.head.querySelector('meta[' + attr + '="' + key + '"]');
  if (!el) { el = document.createElement("meta"); el.setAttribute(attr, key); document.head.appendChild(el); }
  el.setAttribute("content", content);
}
function setCanonical(href) {
  var el = document.head.querySelector('link[rel="canonical"]');
  if (!el) { el = document.createElement("link"); el.setAttribute("rel", "canonical"); document.head.appendChild(el); }
  el.setAttribute("href", href);
}
const SEO_DEF_TITLE = "Mictlán · Decoración gótica, esotérica y alternativa";
const SEO_DEF_DESC = "Mictlán es una tienda de decoración gótica, esotérica y alternativa. Encuentra artículos dark, Halloween, Baphomet, ouija, tarot, horror, vampírico, Día de Muertos, velas, regalos y decoración inspirada en el mundo místico y oscuro.";
function productSeoDesc(p) {
  var cat = (window.CATEGORIES || []).find(function (c) { return c.id === p.cat; });
  var catName = cat ? cat.name : "";
  var price = p.draft ? "" : (p.price ? " · desde $" + p.price + " MXN" : "");
  var body = p.desc || ("Pieza de la colección " + (catName || "Mictlán") + ".");
  return clipTxt(p.name + (catName ? " — " + catName : "") + price + ". " + body + " Envíos a todo México.", 158);
}
function applySeo(route) {
  var title = SEO_DEF_TITLE, desc = SEO_DEF_DESC;
  var url = SITE + routeToPath(route.page, route.params);
  var img = SITE + "/img/og-mictlan.jpg";
  if (route.page === "product") {
    var p = (window.PRODUCTS || []).find(function (x) { return x.id === (route.params && route.params.id); });
    if (p) { title = p.name + " · Mictlán"; desc = productSeoDesc(p); img = absUrl(p.img); }
  } else if (route.page === "catalog") {
    var c = route.params && route.params.cat && (window.CATEGORIES || []).find(function (x) { return x.id === route.params.cat; });
    title = (c ? c.name : "Tienda") + " · Mictlán";
    desc = clipTxt("Explora " + (c ? c.name : "toda la tienda") + " en Mictlán — decoración gótica, esotérica y alternativa. " + SEO_DEF_DESC, 158);
  } else if (route.page === "cart") { title = "Tu carrito · Mictlán"; }
  document.title = title;
  setMetaTag("name", "description", desc);
  setMetaTag("property", "og:title", title);
  setMetaTag("property", "og:description", desc);
  setMetaTag("property", "og:url", url);
  setMetaTag("property", "og:image", img);
  setMetaTag("name", "twitter:title", title);
  setMetaTag("name", "twitter:description", desc);
  setMetaTag("name", "twitter:image", img);
  setCanonical(url);
}

function App() {
  const [route, setRoute] = useStateApp(() => pathToRoute(window.location.pathname));
  const [cart, setCart] = useStateApp(() => {
    try { return JSON.parse(localStorage.getItem("mictlan_cart") || "[]"); } catch (e) { return []; }
  });

  useEffectApp(() => { localStorage.setItem("mictlan_cart", JSON.stringify(cart)); }, [cart]);

  /* favoritos persistentes */
  const [favs, setFavs] = useStateApp(() => {
    try { return JSON.parse(localStorage.getItem("mictlan_favs") || "[]"); } catch (e) { return []; }
  });
  useEffectApp(() => { localStorage.setItem("mictlan_favs", JSON.stringify(favs)); }, [favs]);
  const toggleFav = useCallback((id) => setFavs(prev => prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id]), []);
  const isFav = useCallback((id) => favs.includes(id), [favs]);

  /* catálogo dinámico desde Firestore (si el backend está configurado);
     si no, se queda el catálogo estático de data.jsx */
  const [dataVersion, setDataVersion] = useStateApp(0);
  useEffectApp(() => {
    if (typeof window.loadCatalog !== "function") return;
    let alive = true;
    window.loadCatalog().then(function (data) {
      if (alive && data) {
        window.CATEGORIES = data.categories;
        window.PRODUCTS = data.products;
        setDataVersion(function (v) { return v + 1; });
      }
    });
    return function () { alive = false; };
  }, []);

  /* sincroniza el estado con el botón atrás/adelante del navegador */
  useEffectApp(() => {
    const onPop = () => setRoute(pathToRoute(window.location.pathname));
    window.addEventListener("popstate", onPop);
    return () => window.removeEventListener("popstate", onPop);
  }, []);

  /* SEO: título + metadatos por página/producto (Google ejecuta el JS y los lee) */
  useEffectApp(() => { applySeo(route); }, [route, dataVersion]);

  /* cursor planchette en todo el sitio */
  useEffectApp(() => {
    if (window.matchMedia && window.matchMedia("(pointer:fine)").matches) {
      document.documentElement.style.cursor = PLANCHETTE_CURSOR;
    }
  }, []);

  const navigate = useCallback((page, params = {}) => {
    setRoute({ page, params });
    try {
      const path = routeToPath(page, params);
      if (window.location.pathname !== path) window.history.pushState({ page: page, params: params }, "", path);
    } catch (e) {}
    const sc = document.querySelector(".app-scroll");
    if (params.quiz) {
      setTimeout(() => { const q = document.getElementById("quiz"); if (q && sc) sc.scrollTo({ top: q.offsetTop - 110, behavior: "smooth" }); }, 60);
    } else if (sc) {
      sc.scrollTo({ top: 0 });
    }
  }, []);

  const addToCart = useCallback((p, qty = 1, opt) => {
    setCart(prev => {
      const okey = (o) => o ? (o.size + "/" + o.color + "/" + (o.model || "") + "/" + (o.aroma || "")) : "";
      const key = p.id + "|" + okey(opt);
      const idx = prev.findIndex(it => (it.id + "|" + okey(it.opt)) === key);
      if (idx >= 0) { const cp = [...prev]; cp[idx] = { ...cp[idx], qty: cp[idx].qty + qty }; return cp; }
      const price = (opt && opt.price != null) ? opt.price : p.price;
      return [...prev, { id: p.id, name: p.name, price, motif: p.motif, color: p.color, qty, opt: opt || null }];
    });
  }, []);

  const setQty = useCallback((i, q) => setCart(prev => prev.map((it, idx) => idx === i ? { ...it, qty: q } : it)), []);
  const removeItem = useCallback((i) => setCart(prev => prev.filter((_, idx) => idx !== i)), []);

  const cartCount = cart.reduce((n, it) => n + it.qty, 0);
  const cartTotal = cart.reduce((n, it) => n + it.price * it.qty, 0);

  const ctx = { route, navigate, cart, addToCart, setQty, removeItem, cartCount, cartTotal, favs, toggleFav, isFav, favCount: favs.length };

  let Page = HomePage;
  if (route.page === "catalog") Page = CatalogPage;
  else if (route.page === "product") Page = ProductPage;
  else if (route.page === "cart") Page = CartPage;
  else if (route.page === "terminos") Page = TermsPage;
  else if (route.page === "privacidad") Page = PrivacyPage;
  else if (route.page === "faq") Page = FaqPage;
  else if (route.page === "envios") Page = EnviosPage;
  else if (route.page === "cambios") Page = CambiosPage;
  else if (route.page === "tallas") Page = TallasPage;

  return a(AppCtx.Provider, { value: ctx },
    a("div", { className: "app-scroll" },
      a(Header, null),
      a(Page, { key: route.page + JSON.stringify(route.params) }),
      a(Footer, null)
    ),
    a(SpiritPlanchette, null)
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(a(App, null));
