// src/components.jsx — shared layout pieces (Header, Footer, Reveal, icons, modal)
const { useState, useEffect, useRef } = React;

/* ─── Icons ─────────────────────────────────────────────── */
const Icon = ({ name, size = 16 }) => {
  const paths = {
    arrow: <path d="M5 12h14M13 5l7 7-7 7" stroke="currentColor" strokeWidth="1.6" fill="none" strokeLinecap="round" strokeLinejoin="round"/>,
    'arrow-up-right': <path d="M7 17L17 7M7 7h10v10" stroke="currentColor" strokeWidth="1.6" fill="none" strokeLinecap="round" strokeLinejoin="round"/>,
    close: <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>,
    menu: <path d="M4 7h16M4 12h16M4 17h16" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>,
    mail: <g stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 7l9 6 9-6"/></g>,
    instagram: <g stroke="currentColor" strokeWidth="1.5" fill="none"><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.5" cy="6.5" r="0.8" fill="currentColor"/></g>,
    linkedin: <g fill="currentColor"><path d="M4.98 3.5A2.5 2.5 0 1 1 5 8.5a2.5 2.5 0 0 1-.02-5zM3 9.5h4V21H3V9.5zM9 9.5h3.8v1.6h.05c.53-1 1.84-2.06 3.79-2.06 4.05 0 4.8 2.66 4.8 6.13V21h-4v-5.2c0-1.24-.02-2.83-1.73-2.83-1.73 0-2 1.35-2 2.74V21h-4V9.5z"/></g>,
    facebook: <path fill="currentColor" d="M13 21v-7h2.3l.3-3H13V9c0-.9.3-1.5 1.6-1.5h1.7V4.8c-.3 0-1.3-.1-2.4-.1-2.4 0-4 1.5-4 4.1V11H8v3h2v7h3z"/>,
    download: <g stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v12m0 0l-4-4m4 4l4-4M5 21h14"/></g>,
    play: <path d="M8 5v14l11-7z" fill="currentColor"/>,
    chevron: <path d="M9 18l6-6-6-6" stroke="currentColor" strokeWidth="1.6" fill="none" strokeLinecap="round" strokeLinejoin="round"/>,
    plus: <path d="M12 5v14M5 12h14" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>,
    map: <g stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round"><path d="M21 10c0 7-9 13-9 13S3 17 3 10a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></g>,
    phone: <path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.12.96.37 1.9.72 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.35 1.85.6 2.81.72A2 2 0 0 1 22 16.92z" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/>,
    quote: <path d="M7 7c-2 0-3 1-3 3v6h6V10H6c0-1 1-2 3-2V7zm10 0c-2 0-3 1-3 3v6h6V10h-4c0-1 1-2 3-2V7z" fill="currentColor"/>,
    search: <g stroke="currentColor" strokeWidth="1.6" fill="none"><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3" strokeLinecap="round"/></g>,
    check: <path d="M5 12l5 5L20 7" stroke="currentColor" strokeWidth="1.8" fill="none" strokeLinecap="round" strokeLinejoin="round"/>,
    trophy: <g stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round"><path d="M8 4h8v5a4 4 0 0 1-8 0V4z"/><path d="M16 5h3a1 1 0 0 1 1 1v2a3 3 0 0 1-4 3M8 5H5a1 1 0 0 0-1 1v2a3 3 0 0 0 4 3"/><path d="M12 13v3M9 20h6M10 20l1-4h2l1 4"/></g>,
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
      {paths[name]}
    </svg>
  );
};

/* ─── Idioma (ES/EN) ────────────────────────────────────── */
// t('texto español', 'english text') — si falta el inglés, cae al español.
const LangContext = React.createContext({ lang: 'es', setLang: () => {}, t: (es) => es });
const useLang = () => React.useContext(LangContext);

const LangProvider = ({ children }) => {
  const initial = (() => {
    try {
      const p = new URLSearchParams(window.location.search).get('lang');
      if (p === 'en' || p === 'es') return p;
      const s = localStorage.getItem('lpde_lang');
      if (s === 'en' || s === 'es') return s;
    } catch (e) {}
    return 'es';
  })();
  const [lang, setLangState] = useState(initial);
  const setLang = (l) => {
    setLangState(l);
    try { localStorage.setItem('lpde_lang', l); } catch (e) {}
  };
  useEffect(() => { document.documentElement.lang = lang; }, [lang]);
  const t = React.useCallback((es, en) => (lang === 'en' && en != null ? en : es), [lang]);
  return <LangContext.Provider value={{ lang, setLang, t }}>{children}</LangContext.Provider>;
};

const LangToggle = () => {
  const { lang, setLang } = useLang();
  return (
    <button
      className="lang-toggle"
      onClick={() => setLang(lang === 'es' ? 'en' : 'es')}
      aria-label={lang === 'es' ? 'Switch to English' : 'Cambiar a español'}
      title={lang === 'es' ? 'Switch to English' : 'Cambiar a español'}
    >
      <span className={lang === 'es' ? 'on' : ''}>ES</span>
      <span className="lang-sep">/</span>
      <span className={lang === 'en' ? 'on' : ''}>EN</span>
    </button>
  );
};

/* ─── useReveal hook + Reveal wrapper ───────────────────── */
const useReveal = () => {
  useEffect(() => {
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          e.target.classList.add('in');
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.12, rootMargin: '0px 0px -50px 0px' });
    document.querySelectorAll('.reveal:not(.in)').forEach(el => io.observe(el));
    return () => io.disconnect();
  });
};

/* ─── Animated count-up ─────────────────────────────────── */
const CountUp = ({ to, duration = 1400, suffix = '' }) => {
  const [val, setVal] = useState(0);
  const ref = useRef(null);
  const started = useRef(false);
  useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting && !started.current) {
          started.current = true;
          const start = performance.now();
          const tick = (now) => {
            const t = Math.min(1, (now - start) / duration);
            const eased = 1 - Math.pow(1 - t, 3);
            setVal(Math.round(eased * to));
            if (t < 1) requestAnimationFrame(tick);
          };
          requestAnimationFrame(tick);
        }
      });
    }, { threshold: 0.3 });
    io.observe(ref.current);
    return () => io.disconnect();
  }, [to, duration]);
  return <span ref={ref}>{val}{suffix}</span>;
};

/* ─── Header / Nav ──────────────────────────────────────── */
const NAV_ITEMS = [
  { id: 'presentacion', label: 'Presentación', en: 'About' },
  { id: 'equipo', label: 'Equipo', en: 'Team' },
  { id: 'noticias', label: 'Noticias y recursos', en: 'News & Resources' },
  { id: 'formacion', label: 'Formación', en: 'Training' },
  { id: 'calendario', label: 'Calendario', en: 'Calendar' },
  { id: 'snde', label: 'Selección Nacional', en: 'National Team' },
  { id: 'admision', label: 'Admisión', en: 'Membership' },
  { id: 'tnde', label: 'TNDE', en: 'TNDE' },
];

const Header = ({ page, setPage }) => {
  const { t } = useLang();
  const [menuOpen, setMenuOpen] = useState(false);

  // Menú móvil: bloquear scroll del fondo + cerrar con Esc
  useEffect(() => {
    if (!menuOpen) return;
    const onKey = (e) => { if (e.key === 'Escape') setMenuOpen(false); };
    document.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => {
      document.removeEventListener('keydown', onKey);
      document.body.style.overflow = '';
    };
  }, [menuOpen]);

  const go = (id) => { setMenuOpen(false); setPage(id); };

  return (
    <header className="nav">
      <div className="nav-inner">
        <div className="nav-logo" onClick={() => go('presentacion')} aria-label="Inicio LPDE">
          <img src="assets/logo-lpde-red.png" alt="LPDE — Liga Peruana de Debate Escolar"/>
        </div>
        <nav className="nav-links">
          {NAV_ITEMS.map(item => (
            <button
              key={item.id}
              onClick={() => setPage(item.id)}
              className={`nav-link ${page === item.id ? 'active' : ''}`}
              data-comment-anchor={`nav-${item.id}`}
            >
              {t(item.label, item.en)}
            </button>
          ))}
        </nav>
        <div className="nav-cta">
          <LangToggle/>
          <button
            className="nav-login"
            onClick={() => setPage('colegios-miembros')}
            title={t('Área de formación para colegios miembros', 'Training area for member schools')}
          >
            {t('Iniciar sesión', 'Log in')}
          </button>
          <a href="https://www.instagram.com/lpdebate_org/" target="_blank" rel="noopener" className="nav-icon" title="Instagram"><Icon name="instagram"/></a>
          <a href="https://www.linkedin.com/company/lpdebate/" target="_blank" rel="noopener" className="nav-icon" title="LinkedIn"><Icon name="linkedin"/></a>
          <button className="nav-burger" onClick={() => setMenuOpen(true)} aria-label={t('Abrir menú', 'Open menu')} aria-expanded={menuOpen}>
            <Icon name="menu" size={22}/>
          </button>
        </div>
      </div>

      {/* Portal a body: el backdrop-filter del .nav crea un containing block
          que atraparía (y recortaría) este overlay position:fixed */}
      {menuOpen && ReactDOM.createPortal(
        <div className="nav-menu" role="dialog" aria-modal="true">
          <div className="nav-menu-top">
            <img src="assets/logo-lpde-white.png" alt="LPDE" style={{ height: 28, width: 'auto' }}/>
            <button className="nav-menu-close" onClick={() => setMenuOpen(false)} aria-label={t('Cerrar menú', 'Close menu')}>
              <Icon name="close" size={22}/>
            </button>
          </div>
          <nav className="nav-menu-links">
            {NAV_ITEMS.map((item, i) => (
              <button key={item.id} onClick={() => go(item.id)}
                className={`nav-menu-link ${page === item.id ? 'active' : ''}`}
                style={{ animationDelay: `${60 + i * 35}ms` }}>
                <span className="nav-menu-num">{String(i + 1).padStart(2, '0')}</span>
                {t(item.label, item.en)}
              </button>
            ))}
          </nav>
          <div className="nav-menu-bottom">
            <button className="nav-menu-session" onClick={() => go('colegios-miembros')}>
              {t('Iniciar sesión · Colegios miembros', 'Log in · Member schools')} <Icon name="arrow" size={14}/>
            </button>
            <div style={{ display: 'flex', gap: 8 }}>
              <a href="https://www.instagram.com/lpdebate_org/" target="_blank" rel="noopener" className="nav-icon" style={{ borderColor: '#2A2A30', color: '#fff' }}><Icon name="instagram"/></a>
              <a href="https://www.linkedin.com/company/lpdebate/" target="_blank" rel="noopener" className="nav-icon" style={{ borderColor: '#2A2A30', color: '#fff' }}><Icon name="linkedin"/></a>
              <a href="mailto:contacto@lpdebate.org" className="nav-icon" style={{ borderColor: '#2A2A30', color: '#fff' }}><Icon name="mail"/></a>
            </div>
          </div>
        </div>,
        document.body
      )}
    </header>
  );
};

/* ─── Footer ────────────────────────────────────────────── */
const Footer = ({ setPage }) => {
  const { t } = useLang();
  return (
    <footer className="footer">
      <div className="shell">
        <div className="footer-grid">
          <div>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 36, lineHeight: 1, color: '#fff', marginBottom: 18 }}>
              Liga Peruana<br/>de <em style={{ color: 'var(--red)', fontStyle: 'italic' }}>Debate Escolar</em>
            </div>
            <p style={{ color: '#9C9AA0', fontSize: 14, maxWidth: 380, lineHeight: 1.6 }}>
              {t('La red más grande de debate escolar del Perú. 103 colegios, 11 regiones, 3 mundiales consecutivos.',
                 'Peru’s largest school debate network. 103 schools, 11 regions, 3 consecutive world titles.')}
            </p>
            <div style={{ display: 'flex', gap: 8, marginTop: 24 }}>
              <a href="https://www.instagram.com/lpdebate_org/" target="_blank" rel="noopener" className="nav-icon" style={{ borderColor: '#2A2A30', color: '#fff' }}><Icon name="instagram"/></a>
              <a href="https://www.linkedin.com/company/lpdebate/" target="_blank" rel="noopener" className="nav-icon" style={{ borderColor: '#2A2A30', color: '#fff' }}><Icon name="linkedin"/></a>
              <a href="mailto:contacto@lpdebate.org" className="nav-icon" style={{ borderColor: '#2A2A30', color: '#fff' }}><Icon name="mail"/></a>
            </div>
          </div>
          <div>
            <h4>{t('Navega', 'Explore')}</h4>
            <ul style={{ listStyle: 'none', display: 'flex', flexDirection: 'column', gap: 10, fontSize: 14 }}>
              {NAV_ITEMS.slice(0, 5).map(i => (
                <li key={i.id}><a onClick={() => setPage(i.id)} style={{ cursor: 'pointer' }}>{t(i.label, i.en)}</a></li>
              ))}
              <li><a onClick={() => setPage('colegios-miembros')} style={{ cursor: 'pointer' }}>{t('Iniciar sesión · Miembros', 'Log in · Members')}</a></li>
            </ul>
          </div>
          <div>
            <h4>{t('Programas', 'Programs')}</h4>
            <ul style={{ listStyle: 'none', display: 'flex', flexDirection: 'column', gap: 10, fontSize: 14 }}>
              {NAV_ITEMS.slice(5).map(i => (
                <li key={i.id}><a onClick={() => setPage(i.id)} style={{ cursor: 'pointer' }}>{t(i.label, i.en)}</a></li>
              ))}
              <li><a href="https://cidedidactica.org/metadidactas/" target="_blank" rel="noopener">Metadidactas ↗</a></li>
            </ul>
          </div>
          <div>
            <h4>{t('Contacto', 'Contact')}</h4>
            <ul style={{ listStyle: 'none', display: 'flex', flexDirection: 'column', gap: 10, fontSize: 14 }}>
              <li><a href="mailto:contacto@lpdebate.org">contacto@lpdebate.org</a></li>
              <li><a href="tel:+51944123447">+51 944 123 447</a></li>
              <li style={{ color: '#9C9AA0', fontSize: 12, marginTop: 6 }}>METADIDACTAS S.A.C.<br/>RUC 20611296101</li>
            </ul>
          </div>
        </div>
        <div className="footer-bottom">
          <div className="kicker">© 2026 LPDE · METADIDACTAS S.A.C. · {t('Todos los derechos reservados', 'All rights reserved')}</div>
          <div className="kicker">{t('Argumentar · Pensar · Convencer', 'Argue · Think · Persuade')}</div>
        </div>
      </div>
    </footer>
  );
};

/* ─── Marquee ───────────────────────────────────────────── */
const Marquee = ({ items }) => {
  const doubled = [...items, ...items];
  return (
    <div className="marquee">
      <div className="marquee-track">
        {doubled.map((t, i) => (
          <React.Fragment key={i}>
            <span style={{ fontStyle: i % 3 === 0 ? 'italic' : 'normal', color: i % 3 === 0 ? 'var(--red)' : 'var(--ink)' }}>{t}</span>
            <span className="dot"></span>
          </React.Fragment>
        ))}
      </div>
    </div>
  );
};

/* ─── Modal ─────────────────────────────────────────────── */
const Modal = ({ open, onClose, children }) => {
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => {
      document.removeEventListener('keydown', onKey);
      document.body.style.overflow = '';
    };
  }, [open, onClose]);
  if (!open) return null;
  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        {children}
      </div>
    </div>
  );
};

/* ─── Page wrapper (handles reveal init + key) ──────────── */
const Page = ({ children, screen }) => {
  useReveal();
  useEffect(() => {
    window.scrollTo({ top: 0, behavior: 'instant' });
  }, []);
  return (
    <main className="page-fade" data-screen-label={screen}>
      {children}
    </main>
  );
};

Object.assign(window, { Icon, useReveal, CountUp, Header, Footer, Marquee, Modal, Page, NAV_ITEMS, LangProvider, useLang, LangToggle });
