/* global React */
const { useState, useEffect, useCallback } = React;

/* ---------------- Iconos ---------------- */
const I = {
  search: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" {...p}><circle cx="11" cy="11" r="7"/><path d="m20 20-3.2-3.2"/></svg>),
  menu: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" {...p}><path d="M4 7h16M4 12h16M4 17h16"/></svg>),
  face: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" {...p}><circle cx="12" cy="12" r="9"/><path d="M9 10h.01M15 10h.01"/><path d="M8.5 14.5c1 1.2 2.2 1.8 3.5 1.8s2.5-.6 3.5-1.8"/></svg>),
  clock: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>),
  level: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M4 18V9M10 18V5M16 18v-6"/></svg>),
  arrow: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M5 12h14M13 6l6 6-6 6"/></svg>),
  download: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 4v11M7 11l5 5 5-5M5 20h14"/></svg>),
  scissors: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="6" cy="6" r="2.6"/><circle cx="6" cy="18" r="2.6"/><path d="M8 8l12 9M8 16L20 7"/></svg>),
  dice: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="3.5" y="3.5" width="17" height="17" rx="4"/><circle cx="8.5" cy="8.5" r="1.2" fill="currentColor" stroke="none"/><circle cx="15.5" cy="8.5" r="1.2" fill="currentColor" stroke="none"/><circle cx="12" cy="12" r="1.2" fill="currentColor" stroke="none"/><circle cx="8.5" cy="15.5" r="1.2" fill="currentColor" stroke="none"/><circle cx="15.5" cy="15.5" r="1.2" fill="currentColor" stroke="none"/></svg>),
  tree: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 3 5 12h4l-3 5h12l-3-5h4z"/><path d="M12 17v4"/></svg>),
  cup: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M4 8h13v4a5 5 0 0 1-5 5H9a5 5 0 0 1-5-5z"/><path d="M17 9h2.5a2.5 2.5 0 0 1 0 5H17"/><path d="M8 3.5c-.6.8-.6 1.7 0 2.5M12 3.5c-.6.8-.6 1.7 0 2.5"/></svg>),
  printer: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M7 9V4h10v5"/><rect x="4" y="9" width="16" height="8" rx="2"/><path d="M7 14h10v6H7z"/></svg>),
  book: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 5.5C10.5 4 8 3.6 4.5 4.2V18c3.5-.6 6 0 7.5 1.5 1.5-1.5 4-2.1 7.5-1.5V4.2C16 3.6 13.5 4 12 5.5z"/><path d="M12 5.5V19.5"/></svg>),
  pawn: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="12" cy="6" r="3"/><path d="M9.5 9c-.7 1.6-.3 3 1 4-1.5.8-2.5 2.3-2.5 4.2V19h8v-1.8c0-1.9-1-3.4-2.5-4.2 1.3-1 1.7-2.4 1-4"/><path d="M6 21h12"/></svg>),
  cards: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="2" y="5" width="13" height="16" rx="2"/><path d="M6 2h13a2 2 0 0 1 2 2v14"/><path d="M6 10h6M6 14h4"/></svg>),
  star: (p) => (<svg viewBox="0 0 24 24" fill="currentColor" {...p}><path d="M12 2.6l2.7 5.9 6.4.7-4.8 4.3 1.3 6.3L12 17.9l-5.6 2.9 1.3-6.3L2.9 9.2l6.4-.7z"/></svg>),
  cart: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 4h2l2.2 11.2a1.5 1.5 0 0 0 1.5 1.2h7.7a1.5 1.5 0 0 0 1.5-1.2L20 7H6"/><circle cx="9.5" cy="20" r="1.4"/><circle cx="17" cy="20" r="1.4"/></svg>),
  insta: (p) => (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="2" y="2" width="20" height="20" rx="5"/><circle cx="12" cy="12" r="5"/><circle cx="17.5" cy="6.5" r="1" fill="currentColor" stroke="none"/></svg>),
};

/* ---------------- Logo: molinillo ---------------- */
function Pinwheel({ className }) {
  return (
    <svg className={className} viewBox="0 0 100 100" aria-hidden="true">
      <g>
        <path d="M50 50 L50 8 A42 42 0 0 1 92 50 Z" fill="var(--coral)"/>
        <path d="M50 50 L92 50 A42 42 0 0 1 50 92 Z" fill="var(--sun)"/>
        <path d="M50 50 L50 92 A42 42 0 0 1 8 50 Z" fill="var(--leaf)"/>
        <path d="M50 50 L8 50 A42 42 0 0 1 50 8 Z" fill="var(--sky)"/>
      </g>
      <circle cx="50" cy="50" r="9" fill="var(--ink)"/>
      <circle cx="50" cy="50" r="3.4" fill="var(--paper)"/>
    </svg>
  );
}

/* ---------------- Datos ---------------- */
const CATS = {
  manualidades: { label: "Manualidades", color: "var(--coral)", soft: "cat-coral", Icon: I.scissors },
  interior:     { label: "Juegos de interior", color: "var(--sky)", soft: "cat-sky", Icon: I.dice },
  mesa:         { label: "Juegos de mesa", color: "var(--grape)", soft: "cat-grape", Icon: I.pawn },
  aire:         { label: "Aire libre", color: "var(--leaf)", soft: "cat-leaf", Icon: I.tree },
  baraja:       { label: "Baraja Española", color: "var(--coral)", soft: "cat-coral", Icon: I.cards },
  recetas:      { label: "Recetas", color: "var(--sun)", soft: "cat-sun", Icon: I.cup },
  imprimibles:  { label: "Imprimibles", color: "var(--berry)", soft: "cat-berry", Icon: I.printer },
  cuentos:      { label: "Libros recomendados", color: "var(--mint)", soft: "cat-mint", Icon: I.book },
};

const AGES = [
  { key: "all",  label: "Todas", sub: "las edades" },
  { key: "0-2",  label: "0–2",   sub: "años" },
  { key: "3-5",  label: "3–5",   sub: "años" },
  { key: "6-8",  label: "6–8",   sub: "años" },
  { key: "9-12", label: "9–12",  sub: "años" },
];

/* ---------------- Mapeo de fila de Supabase a shape de tarjeta ---------------- */
function mapGameRow(row) {
  return {
    id: row.id,
    cat: row.category,
    title: row.title,
    ages: row.ages,
    isProduct: row.is_product,
    brand: row.brand || undefined,
    rating: row.rating != null ? Number(row.rating) : undefined,
    img: row.cover_image_url || undefined,
    q: row.search_query || undefined,
    url: row.affiliate_url || undefined,
    desc: row.description || undefined,
    time: row.time_estimate || undefined,
    level: row.difficulty || undefined,
    download: row.download_url || undefined,
    steps: row.steps || null,
  };
}

/* ---------------- Modal paso a paso ---------------- */
function StepModal({ card, onClose }) {
  const cat = CATS[card.cat];
  const data = card.steps;
  const [imgFull, setImgFull] = useState(false);

  useEffect(() => {
    const esc = (e) => { if(e.key === "Escape") imgFull ? setImgFull(false) : onClose(); };
    window.addEventListener("keydown", esc);
    document.body.style.overflow = "hidden";
    return () => { window.removeEventListener("keydown", esc); document.body.style.overflow = ""; };
  }, [imgFull]);

  return (
    <div className="modal-backdrop" onClick={(e) => e.target === e.currentTarget && onClose()}>
      <div className="modal" role="dialog" aria-modal="true">
        <div className="modal__header" style={{ background: cat.color }}>
          <span className="modal__cat"><cat.Icon style={{ width:16, height:16 }} /> {cat.label}</span>
          <button className="modal__close" onClick={onClose} aria-label="Cerrar">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"><path d="M18 6 6 18M6 6l12 12"/></svg>
          </button>
        </div>
        <div className="modal__body">
          {!card.isProduct && (
            <div className="modal__cover">
              <img src={card.img} alt={card.title} />
            </div>
          )}
          <div className="modal__content">
            <div className="modal__meta">
              {card.time && <span className="pill"><I.face /> {card.ages.join(" · ")} años</span>}
              {card.time && <span className="pill"><I.clock /> {card.time}</span>}
              {card.level && <span className="pill"><I.level /> {card.level}</span>}
            </div>
            <h2 className="modal__title">{card.title}</h2>
            {data ? (
              <React.Fragment>
                <div className="modal__materials">
                  <h3>{card.cat === "recetas" ? "🥘 Ingredientes" : "🧰 Materiales"}</h3>
                  <ul>{data.materiales.map((m,i) => <li key={i}>{m}</li>)}</ul>
                </div>
                <h3 className="modal__steps-title">{card.cat === "baraja" ? "🃏 Aprende a jugar" : "📋 Paso a paso"}</h3>
                <ol className="modal__steps">
                  {data.pasos.map((p) => (
                    <li key={p.n} className="modal__step">
                      <span className="modal__step-n" style={{ background: cat.color }}>{p.n}</span>
                      <div><strong>{p.tit}</strong><p>{p.desc}</p></div>
                    </li>
                  ))}
                </ol>
                {data.pistas && (
                  <div className="modal__beneficios" style={{marginTop:"12px"}}>
                    <h3>🌳 Ejemplos de pistas para el parque</h3>
                    <div style={{display:"flex",flexDirection:"column",gap:"8px",marginTop:"8px"}}>
                      {data.pistas.map((p,i) => (
                        <div key={i} style={{background:"#fffbf0",borderRadius:"10px",padding:"10px 14px",borderLeft:"4px solid #f4b942"}}>
                          <div style={{fontWeight:700,color:"#e07a00",marginBottom:"4px",fontSize:"13px"}}>Pista {p.n} → {p.lugar}</div>
                          <div style={{color:"#444",fontSize:"14px",lineHeight:1.5,fontStyle:"italic"}}>"{p.texto}"</div>
                        </div>
                      ))}
                    </div>
                  </div>
                )}
                {data.proceso_image_url && (
                  <div className="modal__process">
                    <h3>📸 El proceso en imágenes <span className="modal__zoom-hint">· toca para ampliar</span></h3>
                    <img
                      src={data.proceso_image_url} alt="Paso a paso en imágenes"
                      onClick={() => setImgFull(true)}
                      style={{ cursor: "zoom-in" }}
                    />
                  </div>
                )}
                {data.beneficios && (
                  <div className="modal__beneficios">
                    <h3>✅ Beneficios</h3>
                    <ul>{data.beneficios.map((b,i) => <li key={i}>{b}</li>)}</ul>
                  </div>
                )}
                {data.ideas && (
                  <div className="modal__ideas">
                    <h3>💡 Ideas para jugar después</h3>
                    <ul>{data.ideas.map((idea,i) => <li key={i}>{idea}</li>)}</ul>
                  </div>
                )}
                {data.consejo && (
                  <div className="modal__consejo">
                    <span>💬</span>
                    <p><strong>Consejo:</strong> {data.consejo}</p>
                  </div>
                )}
              </React.Fragment>
            ) : (
              <div className="modal__soon"><p>🚧 El paso a paso llegará muy pronto. ¡Vuelve a visitarnos!</p></div>
            )}
          </div>
        </div>
      </div>

      {imgFull && (
        <div className="imgfull-backdrop" onClick={() => setImgFull(false)}>
          <button className="imgfull-close" onClick={() => setImgFull(false)} aria-label="Cerrar">
            <svg viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2.5" strokeLinecap="round" width="24" height="24"><path d="M18 6 6 18M6 6l12 12"/></svg>
          </button>
          <img src={data.proceso_image_url} alt="Paso a paso ampliado" className="imgfull-img" onClick={e => e.stopPropagation()} />
          <p className="imgfull-hint">Pellizca para hacer zoom • Toca fuera para cerrar</p>
        </div>
      )}
    </div>
  );
}

/* ---------------- Tarjeta de artículo / producto ---------------- */
function Card({ c, hidden, afiliado, onOpen }) {
  const cat = CATS[c.cat];
  const product = c.isProduct;
  const isDownload = !!c.download;
  const url = product ? (c.url || `https://www.amazon.es/s?k=${encodeURIComponent(c.q)}&tag=${encodeURIComponent(afiliado || "")}`) : null;
  return (
    <article className={"card" + (product ? " card--shop" : "") + (hidden ? " hide" : "")}
      onClick={isDownload ? () => {
        const resMap = { "Mandalas.pdf": "pdfMandalas", "Calendario de Rutinas.pdf": "pdfCalendario" };
        const resId = resMap[c.download];
        const url = (resId && window.__resources && window.__resources[resId]) || c.download;
        window.open(url, "_blank");
      } : (!product ? () => onOpen(c) : undefined)}
      style={(!product || isDownload) ? { cursor: "pointer" } : null}>
      <div className="card__media">
        <span className="card__tag" style={{ background: cat.color }}>
          <cat.Icon style={{ width: 13, height: 13 }} /> {cat.label}
        </span>
        <img className="card__img" src={c.img} alt={c.title} loading="lazy" />
        {isDownload
          ? <span className="card__readmore">Descargar PDF <I.download style={{width:13,height:13}} /></span>
          : (!product && <span className="card__readmore">{c.cat === "baraja" ? "Aprende a jugar" : "Ver paso a paso"} <I.arrow style={{width:13,height:13}} /></span>)}
      </div>
      <div className="card__body">
        {product ? (
          <React.Fragment>
            <a href={url} target="_blank" rel="sponsored nofollow noopener" className="card__title" onClick={e => e.stopPropagation()}>{c.title}</a>
            {c.desc && <p className="card__desc">{c.desc}</p>}
            <div className="card__meta">
              <span className="pill"><I.face /> {c.ages.join(" · ")} años</span>
              <span className="pill" style={{ color: "var(--sun)" }}><I.star /> {c.rating.toFixed(1)}</span>
              <span className="pill">{c.brand}</span>
            </div>
            <a className="btn-amz" href={url} target="_blank" rel="sponsored nofollow noopener" onClick={e => e.stopPropagation()}><I.cart /> Ver en Amazon</a>
            <span className="shopcard__aff">Enlace de afiliado</span>
          </React.Fragment>
        ) : (
          <React.Fragment>
            <span className="card__title">{c.title}</span>
            <div className="card__meta">
              <span className="pill"><I.face /> {c.ages.join(" · ")} años</span>
              <span className="pill"><I.clock /> {c.time}</span>
              <span className="pill"><I.level /> {c.level}</span>
            </div>
          </React.Fragment>
        )}
      </div>
    </article>
  );
}

/* ---------------- Hueco de anuncio ---------------- */
function AdSlot({ kind, show }) {
  return (
    <div className={"adslot adslot--" + kind + (show ? "" : " is-hidden")}>
      <span className="adslot__label">Publicidad</span>
      <span className="adslot__hint">Espacio reservado · <b>se integra sin molestar la lectura</b></span>
    </div>
  );
}

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "tema": "confeti",
  "fuente": "Baloo 2",
  "mostrarAnuncios": true,
  "heroFoto": true,
  "afiliado": "tuetiqueta-21"
}/*EDITMODE-END*/;

/* ---------------- Datos del titular ---------------- */
const TITULAR = {
  nombre: "Ana Fernández Morante",
  dni: "74XXX",
  dir: "Av. Ilustración 85, 18016 Granada (España)",
  email: "ideasparajugarenfamilia@gmail.com",
  web: "www.ideasparajugarenfamilia.com",
};

/* ---------------- Páginas legales ---------------- */
const LEGAL = {
  "sobre": {
    title: "Sobre nosotros",
    icon: "💛",
    body: (
      <React.Fragment>
        <p><strong>Ideas para Jugar en Familia</strong> nace con una idea muy sencilla: ayudar a madres, padres y cuidadores a pasar más tiempo de calidad con los niños, lejos de las pantallas.</p>
        <p>Aquí encontrarás manualidades, juegos de interior y exterior, recetas fáciles para cocinar con peques, imprimibles, guías para jugar con la baraja española y recomendaciones de libros y juegos de mesa. Todo pensado para disfrutar en familia, organizado por edades para que encuentres rápido lo que buscas.</p>
        <p>Cada propuesta se explica paso a paso, con materiales sencillos y económicos que probablemente ya tengas en casa. Creemos que jugar juntos es una de las mejores formas de aprender, crecer y crear recuerdos.</p>
        <p>El sitio está creado y gestionado por <strong>{TITULAR.nombre}</strong>. Si tienes ideas, sugerencias o quieres colaborar, escríbenos a <a href={"mailto:" + TITULAR.email}>{TITULAR.email}</a>. ¡Nos encanta escuchar a nuestra comunidad!</p>
      </React.Fragment>
    ),
  },
  "contacto": {
    title: "Contacto",
    icon: "✉️",
    body: (
      <React.Fragment>
        <p>¿Tienes alguna duda, sugerencia o propuesta de colaboración? Estaremos encantados de leerte.</p>
        <div className="legal__card">
          <p><strong>Responsable:</strong> {TITULAR.nombre}</p>
          <p><strong>Email:</strong> <a href={"mailto:" + TITULAR.email}>{TITULAR.email}</a></p>
          <p><strong>Dirección:</strong> {TITULAR.dir}</p>
          <p><strong>Instagram:</strong> <a href="https://www.instagram.com/ideasparajugarenfamilia" target="_blank" rel="noopener">@ideasparajugarenfamilia</a></p>
        </div>
        <p>Intentamos responder a todos los mensajes en un plazo máximo de 48–72 horas laborables. Para cualquier asunto relacionado con tus datos personales, indícalo en el asunto del correo.</p>
      </React.Fragment>
    ),
  },
  "privacidad": {
    title: "Política de privacidad",
    icon: "🔒",
    body: (
      <React.Fragment>
        <p>En cumplimiento del Reglamento (UE) 2016/679 (RGPD) y de la Ley Orgánica 3/2018 (LOPDGDD), te informamos sobre el tratamiento de tus datos personales en este sitio web.</p>
        <h4>1. Responsable del tratamiento</h4>
        <p>{TITULAR.nombre} · DNI {TITULAR.dni}<br/>{TITULAR.dir}<br/>Email: <a href={"mailto:" + TITULAR.email}>{TITULAR.email}</a></p>
        <h4>2. ¿Qué datos tratamos y con qué finalidad?</h4>
        <p>Este sitio es principalmente informativo. Solo tratamos datos personales cuando nos los facilitas voluntariamente, por ejemplo al escribirnos por correo electrónico. En ese caso, usamos tu dirección y el contenido del mensaje únicamente para responder a tu consulta.</p>
        <p>Además, mediante cookies y tecnologías similares, terceros (como proveedores de publicidad y analítica) pueden recoger datos de navegación de forma automática. Consulta el <em>Aviso de cookies</em> para más detalle.</p>
        <h4>3. Legitimación</h4>
        <p>La base legal es tu consentimiento (al escribirnos o al aceptar las cookies) y el interés legítimo en mantener y mejorar el sitio web.</p>
        <h4>4. Conservación</h4>
        <p>Conservamos los datos el tiempo necesario para atender tu solicitud y, después, durante los plazos legalmente exigibles. Los datos recogidos por cookies se conservan según las políticas de cada proveedor.</p>
        <h4>5. Destinatarios</h4>
        <p>No vendemos ni cedemos tus datos. Pueden acceder a datos de navegación los proveedores de servicios de analítica y publicidad (por ejemplo, Google) y plataformas de afiliación (por ejemplo, Amazon), conforme a sus propias políticas.</p>
        <h4>6. Tus derechos</h4>
        <p>Puedes ejercer tus derechos de acceso, rectificación, supresión, oposición, limitación y portabilidad escribiendo a <a href={"mailto:" + TITULAR.email}>{TITULAR.email}</a>. También puedes reclamar ante la Agencia Española de Protección de Datos (<a href="https://www.aepd.es" target="_blank" rel="noopener">www.aepd.es</a>).</p>
        <h4>7. Enlaces de afiliados</h4>
        <p>Algunos enlaces de este sitio son enlaces de afiliado de Amazon. Como afiliados de Amazon, podemos recibir una pequeña comisión por las compras que cumplan los requisitos, sin coste adicional para ti.</p>
      </React.Fragment>
    ),
  },
  "cookies": {
    title: "Aviso de cookies",
    icon: "🍪",
    body: (
      <React.Fragment>
        <p>Este sitio web utiliza cookies propias y de terceros para mejorar tu experiencia, analizar el tráfico y mostrar publicidad.</p>
        <h4>¿Qué son las cookies?</h4>
        <p>Son pequeños archivos que se descargan en tu dispositivo al visitar una web y que permiten recordar información sobre tu navegación.</p>
        <h4>Tipos de cookies que usamos</h4>
        <ul>
          <li><strong>Técnicas (necesarias):</strong> permiten el funcionamiento básico del sitio. No requieren consentimiento.</li>
          <li><strong>Analíticas:</strong> nos ayudan a entender cómo se usa la web (por ejemplo, mediante Google Analytics) para mejorarla.</li>
          <li><strong>Publicitarias:</strong> proveedores como Google y sus partners pueden usarlas para mostrar anuncios relevantes.</li>
          <li><strong>De afiliación:</strong> plataformas como Amazon pueden usar cookies para atribuir correctamente las compras realizadas a través de nuestros enlaces.</li>
        </ul>
        <h4>Gestión de cookies</h4>
        <p>Puedes aceptar, rechazar o configurar las cookies desde el banner de consentimiento y, en cualquier momento, eliminarlas o bloquearlas desde la configuración de tu navegador (Chrome, Firefox, Safari, Edge…).</p>
        <p>Ten en cuenta que desactivar algunas cookies puede afectar al correcto funcionamiento de ciertas partes del sitio.</p>
        <h4>Más información</h4>
        <p>Para cualquier duda sobre el uso de cookies, escríbenos a <a href={"mailto:" + TITULAR.email}>{TITULAR.email}</a>.</p>
      </React.Fragment>
    ),
  },
};

function CookieBanner({ onOpenCookies }) {
  const [show, setShow] = useState(false);
  useEffect(() => {
    try { if (!localStorage.getItem("ipjf_cookies")) setShow(true); } catch(e) { setShow(true); }
  }, []);
  const decide = (val) => {
    try { localStorage.setItem("ipjf_cookies", val); } catch(e) {}
    setShow(false);
  };
  if (!show) return null;
  return (
    <div className="cookie-banner" role="dialog" aria-live="polite" aria-label="Aviso de cookies">
      <div className="cookie-banner__inner">
        <div className="cookie-banner__text">
          <span className="cookie-banner__emoji">🍪</span>
          <p>Usamos cookies propias y de terceros para analizar el tráfico y mostrar publicidad. Puedes aceptarlas, rechazarlas o leer más en nuestro <a href="#" onClick={(e)=>{e.preventDefault();onOpenCookies();}}>Aviso de cookies</a>.</p>
        </div>
        <div className="cookie-banner__btns">
          <button className="cookie-btn cookie-btn--ghost" onClick={()=>decide("rejected")}>Rechazar</button>
          <button className="cookie-btn cookie-btn--solid" onClick={()=>decide("accepted")}>Aceptar todo</button>
        </div>
      </div>
    </div>
  );
}

function LegalModal({ page, onClose }) {
  const data = LEGAL[page];
  useEffect(() => {
    const esc = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", esc);
    document.body.style.overflow = "hidden";
    return () => { window.removeEventListener("keydown", esc); document.body.style.overflow = ""; };
  }, []);
  if (!data) return null;
  return (
    <div className="modal-backdrop" onClick={(e) => e.target === e.currentTarget && onClose()}>
      <div className="modal modal--legal" role="dialog" aria-modal="true">
        <div className="modal__header" style={{ background: "var(--coral)" }}>
          <span className="modal__cat">{data.icon} {data.title}</span>
          <button className="modal__close" onClick={onClose} aria-label="Cerrar">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"><path d="M18 6 6 18M6 6l12 12"/></svg>
          </button>
        </div>
        <div className="modal__body">
          <div className="modal__content legal__content">
            <h2 className="modal__title">{data.title}</h2>
            {data.body}
          </div>
        </div>
      </div>
    </div>
  );
}

/* ---------------- Navegación de categorías ---------------- */
const NAV_ITEMS = [
  { key:"manualidades", label:"Manualidades", href:"manualidades.html", color:"var(--coral)", soft:"cat-coral", Icon:I.scissors, cats:["manualidades"], img:"images/nav-scissors-tight.png" },
  { key:"juegos", label:"Juegos", href:"juegos.html", color:"var(--sky)", soft:"cat-sky", Icon:I.dice, cats:["interior","aire"], img:"images/nav-ball-tight.png" },
  { key:"mesa", label:"Juegos de mesa", href:"juegos-de-mesa.html", color:"var(--grape)", soft:"cat-grape", Icon:I.pawn, cats:["mesa"], img:"images/nav-pawn-tight.png" },
  { key:"baraja", label:"Baraja Española", href:"baraja-espanola.html", color:"var(--coral)", soft:"cat-coral", Icon:I.cards, cats:["baraja"], img:"images/nav-cards-tight.png" },
  { key:"recetas", label:"Recetas", href:"recetas.html", color:"var(--sun)", soft:"cat-sun", Icon:I.cup, cats:["recetas"], img:"images/nav-chef-tight.png" },
  { key:"cuentos", label:"Libros", href:"libros.html", color:"var(--mint)", soft:"cat-mint", Icon:I.book, cats:["cuentos"], img:"images/nav-book-tight.png" },
];
const navCount = (item) => (window.CARDS || []).filter(c => item.cats.includes(c.cat)).length;

function SiteHeader({ active, q, setQ, searchOpen, setSearchOpen, menuOpen, setMenuOpen }) {
  return (
    <header className="topbar">
      <div className="navbanner">
        <span className="navbanner__deco navbanner__deco--1"></span>
        <span className="navbanner__deco navbanner__deco--2"></span>
        <span className="navbanner__deco navbanner__deco--3"></span>
        <span className="navbanner__deco navbanner__deco--4"></span>
        <span className="navbanner__deco navbanner__deco--5"></span>
        <span className="navbanner__deco navbanner__deco--6"></span>
        <span className="navbanner__deco navbanner__deco--7"></span>
        <span className="navbanner__deco navbanner__deco--8"></span>
        <span className="navbanner__deco navbanner__deco--9"></span>
        <span className="navbanner__deco navbanner__deco--10"></span>
        <a className="brand navbanner__brand" href="index.html">
          <Pinwheel className="brand__mark" />
          <span className="brand__text">
            <span className="brand__name">Ideas para <b>Jugar</b> en Familia</span>
            <span className="brand__tag">Planes · Juegos · Manualidades</span>
          </span>
        </a>
        <span className="navbanner__divider"></span>
        <nav className="navbanner__items">
          {NAV_ITEMS.map(item => (
            <a key={item.key} className="navbanner__item" href={item.href} aria-current={active===item.key?"page":undefined}>
              <span className="navbanner__icon"><img src={item.img} alt="" /></span>
              <span className="navbanner__label">{item.label}</span>
            </a>
          ))}
        </nav>
        <div className="navbanner__utils">
          {searchOpen && (
            <input
              autoFocus
              className="topsearch"
              placeholder="Buscar actividad…"
              value={q}
              onChange={(e) => setQ(e.target.value)}
              style={{ width: 180, padding: "0 16px", borderRadius: 999, border: "2px solid var(--ink)", background: "var(--paper-2)", color: "var(--ink)", fontFamily: "inherit", fontSize: 14, fontWeight: 700 }}
            />
          )}
          <button className="iconbtn" onClick={() => setSearchOpen((v) => !v)} aria-label="Buscar"><I.search /></button>
          <button className="iconbtn hamb" aria-label="Menú" onClick={() => setMenuOpen(v => !v)}><I.menu /></button>
          <a className="iconbtn" href="https://www.instagram.com/ideasparajugarenfamilia" target="_blank" rel="noopener" aria-label="Instagram" style={{ background: "linear-gradient(135deg,#f09433,#e6683c,#dc2743,#cc2366,#bc1888)", border: "none", color: "#fff" }}><I.insta style={{ width:18, height:18 }} /></a>
        </div>
      </div>
    </header>
  );
}

function MobileDrawer({ open, onClose }) {
  if (!open) return null;
  return (
    <div className="mobile-drawer" onClick={onClose}>
      <div className="mobile-drawer__panel" onClick={e => e.stopPropagation()}>
        <div className="mobile-drawer__header">
          <span className="mobile-drawer__title">Categorías</span>
          <button className="modal__close" style={{ background: "var(--paper-3)" }} onClick={onClose}>
            <svg viewBox="0 0 24 24" fill="none" stroke="var(--ink)" strokeWidth="2.5" strokeLinecap="round" width="17" height="17"><path d="M18 6 6 18M6 6l12 12"/></svg>
          </button>
        </div>
        {NAV_ITEMS.map(item => (
          <a key={item.key} className="mobile-drawer__item" href={item.href}>
            <span className="mobile-drawer__dot" style={{ background: item.color }}></span>
            {item.label}
          </a>
        ))}
        <a href="https://www.instagram.com/ideasparajugarenfamilia" target="_blank" rel="noopener" className="mobile-drawer__insta">
          <I.insta style={{ width:18, height:18 }} /> @ideasparajugarenfamilia
        </a>
      </div>
    </div>
  );
}

function SiteFooter({ onLegal }) {
  return (
    <footer className="footer">
      <div className="wrap footer__inner">
        <div className="footer__brand">
          <a className="brand" href="index.html">
            <Pinwheel className="brand__mark" />
            <span className="brand__name">Ideas para <b>Jugar</b> en Familia</span>
          </a>
          <p>Ideas sencillas para pasar más tiempo de calidad jugando en familia, sin pantallas.</p>
          <a href="https://www.instagram.com/ideasparajugarenfamilia" target="_blank" rel="noopener" className="footer__insta-handle" style={{display:"inline-flex",alignItems:"center",gap:"8px",marginTop:"10px",textDecoration:"none"}}>
            <span style={{display:"inline-flex",alignItems:"center",justifyContent:"center",width:32,height:32,borderRadius:8,background:"linear-gradient(135deg,#f09433,#e6683c 25%,#dc2743 50%,#cc2366 75%,#bc1888)",flexShrink:0}}>
              <I.insta style={{width:18,height:18,color:"#fff"}} />
            </span>
            <span style={{color:"#444",fontWeight:600,fontSize:"14px"}}>@ideasparajugarenfamilia</span>
          </a>
        </div>
        <div>
          <h4>Categorías</h4>
          <ul>{NAV_ITEMS.map((c) => <li key={c.key}><a href={c.href}>{c.label}</a></li>)}</ul>
        </div>
        <div>
          <h4>Por edad</h4>
          <ul><li><a href="index.html">Bebés (0-2)</a></li><li><a href="index.html">Preescolar (3-5)</a></li><li><a href="index.html">Primaria (6-8)</a></li><li><a href="index.html">Mayores (9-12)</a></li></ul>
        </div>
        <div>
          <h4>El sitio</h4>
          <ul><li><a href="#" onClick={(e)=>{e.preventDefault();onLegal("sobre");}}>Sobre nosotros</a></li><li><a href="#" onClick={(e)=>{e.preventDefault();onLegal("contacto");}}>Contacto</a></li><li><a href="#" onClick={(e)=>{e.preventDefault();onLegal("privacidad");}}>Política de privacidad</a></li><li><a href="#" onClick={(e)=>{e.preventDefault();onLegal("cookies");}}>Aviso de cookies</a></li></ul>
        </div>
      </div>
      <div className="wrap footer__bottom">
        <span>© 2026 ideasparajugarenfamilia.com — Hecho con cariño 🪁</span>
        <a href="https://www.instagram.com/ideasparajugarenfamilia" target="_blank" rel="noopener" style={{ display:"inline-flex", alignItems:"center", gap:7, fontWeight:800, fontSize:14 }}>
          <I.insta style={{ width:18, height:18, color:"#E1306C" }} /> @ideasparajugarenfamilia
        </a>
        <span>Publicidad gestionada de forma responsable</span>
      </div>
    </footer>
  );
}

/* ---------------- Chrome compartido: fetch a Supabase + estado global ---------------- */
function useSiteChrome() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [legalPage, setLegalPage] = useState(null);
  const [openCard, setOpenCard] = useState(null);
  const [menuOpen, setMenuOpen] = useState(false);
  const [searchOpen, setSearchOpen] = useState(false);
  const [games, setGames] = useState([]);
  const [loading, setLoading] = useState(true);
  const [loadError, setLoadError] = useState(null);

  const loadGames = useCallback(() => {
    setLoading(true);
    setLoadError(null);
    window.supabaseClient
      .from("games")
      .select("*")
      .order("category")
      .order("id")
      .then(({ data, error }) => {
        if (error) { setLoadError(error.message); setLoading(false); return; }
        const catOrder = Object.keys(CATS);
        const sorted = data.map(mapGameRow).sort((a, b) => catOrder.indexOf(a.cat) - catOrder.indexOf(b.cat));
        window.CARDS = sorted;
        setGames(sorted);
        setLoading(false);
      })
      .catch((err) => {
        setLoadError(err.message || "No se pudo conectar con el servidor.");
        setLoading(false);
      });
  }, []);

  useEffect(() => { loadGames(); }, [loadGames]);

  useEffect(() => {
    const root = document.documentElement;
    root.classList.remove("theme-confeti", "theme-pastel", "theme-natural");
    root.classList.add("theme-" + t.tema);
    root.style.setProperty("--font-display", `'${t.fuente}', system-ui, sans-serif`);
  }, [t.tema, t.fuente]);

  return { t, setTweak, legalPage, setLegalPage, openCard, setOpenCard, menuOpen, setMenuOpen, searchOpen, setSearchOpen, games, loading, loadError, loadGames };
}

function SiteTweaksAndModals({ chrome }) {
  const { t, setTweak, legalPage, setLegalPage, openCard, setOpenCard } = chrome;
  return (
    <React.Fragment>
      {openCard && <StepModal card={openCard} onClose={() => setOpenCard(null)} />}
      {legalPage && <LegalModal page={legalPage} onClose={() => setLegalPage(null)} />}
      <CookieBanner onOpenCookies={() => setLegalPage("cookies")} />
      <TweaksPanel>
        <TweakSection label="Estilo de marca" />
        <TweakRadio label="Tema de color" value={t.tema} options={["confeti", "pastel", "natural"]} onChange={(v) => setTweak("tema", v)} />
        <TweakSelect label="Tipografía display" value={t.fuente} options={["Baloo 2", "Fredoka", "Quicksand"]} onChange={(v) => setTweak("fuente", v)} />
        <TweakSection label="Publicidad" />
        <TweakToggle label="Mostrar huecos de anuncios" value={t.mostrarAnuncios} onChange={(v) => setTweak("mostrarAnuncios", v)} />
        <TweakSection label="Portada" />
        <TweakToggle label="Mostrar foto en la cabecera" value={t.heroFoto} onChange={(v) => setTweak("heroFoto", v)} />
        <TweakSection label="Afiliados de Amazon" />
        <TweakText label="Tu etiqueta de afiliado" value={t.afiliado} placeholder="tuetiqueta-21" onChange={(v) => setTweak("afiliado", v)} />
      </TweaksPanel>
    </React.Fragment>
  );
}

Object.assign(window, {
  I, Pinwheel, CATS, AGES, mapGameRow, StepModal, Card, AdSlot, CookieBanner, LegalModal,
  NAV_ITEMS, navCount, SiteHeader, SiteFooter, MobileDrawer, SiteTweaksAndModals, useSiteChrome,
});
