// src/pages-miembros.jsx — Área privada para Colegios Miembros
//
// AUTENTICACIÓN — MAGIC LINK (sin contraseñas)
// ────────────────────────────────────────────
// Backend PHP en lpdebate.org/plataforma/miembros-auth/ (mismo dominio →
// cookie httpOnly de sesión, 30 días):
//   login.php   → POST {correo}: si el colegio está activo, envía enlace
//   acceso.php  → el enlace del correo; setea cookie y vuelve aquí
//   session.php → ¿quién soy? {colegio:{id, nombre}}
//   sesiones.php→ contenido del Sheet de formación (requiere sesión)
//   logout.php  → borra la cookie
// El alta/baja de colegios se administra en el Sheet "Accesos Miembros"
// (estado: activo/suspendido). El hash demo client-side fue eliminado.
//
// VIDEOS
// ──────
// Importante: ningún SPA puede impedir 100% que un usuario autenticado
// comparta la URL del embed. Defensas razonables (no infalibles):
//   - Reproductor con rel=0, modestbranding, sin sugerencias
//   - Watermark superpuesto con el nombre del colegio logueado
//   - Click derecho bloqueado sobre el contenedor del reproductor
//   - Disclaimer visible al usuario

const MIEMBROS_API = 'https://lpdebate.org/plataforma/miembros-auth';

/* ── Filas del Sheet (objetos del backend) → sesiones del dashboard ── */
function rowsToSessions(rows) {
  const out = [];
  for (const raw of rows || []) {
    // Normalizar claves a minúsculas por si los headers cambian de caja
    const row = {};
    for (const k of Object.keys(raw || {})) row[k.trim().toLowerCase()] = raw[k];
    const get = (name) => ((row[name] === undefined || row[name] === null) ? '' : String(row[name]).trim());

    // Saltar filas sin id o marcadas como no publicadas
    const id = get('id');
    if (!id) continue;
    const pub = get('published').toLowerCase();
    if (pub === 'false' || pub === 'no' || pub === '0') continue;

    const materials = [];
    for (let n = 1; n <= 5; n++) {
      const url = get(`material_${n}_url`);
      if (url) {
        materials.push({
          kind: get(`material_${n}_kind`) || 'Material',
          label: get(`material_${n}_label`) || get(`material_${n}_kind`) || 'Descargar',
          url,
        });
      }
    }

    out.push({
      id,
      kind: get('kind') || 'Sesión',
      title: get('title'),
      speaker: get('speaker'),
      date: get('date'),
      duration: get('duration'),
      area: get('area'),
      level: get('level'),
      path: get('path'),
      summary: get('summary'),
      video: get('video'),
      materials,
    });
  }
  return out;
}

/* ── Hook: sesiones desde sesiones.php (requiere cookie), fallback a data.js ── */
function useMiembrosSessions() {
  const D = window.LPDE_DATA;
  const fallback = (D && D.miembros && D.miembros.sessions) || [];
  const [sessions, setSessions] = React.useState(fallback);
  const [status, setStatus] = React.useState('loading'); // loading | live | fallback
  React.useEffect(() => {
    let cancelled = false;
    fetch(`${MIEMBROS_API}/sesiones.php`, { cache: 'no-store', credentials: 'include' })
      .then((r) => r.ok ? r.json() : Promise.reject('http ' + r.status))
      .then((data) => {
        if (cancelled) return;
        const parsed = rowsToSessions(data && data.rows);
        if (parsed.length) { setSessions(parsed); setStatus('live'); }
        else { setStatus('fallback'); }
      })
      .catch((err) => {
        console.warn('[miembros] sesiones.php failed, using fallback:', err);
        if (!cancelled) setStatus('fallback');
      });
    return () => { cancelled = true; };
  }, []);
  return { sessions, status };
}

/* ── Convertir URL de YouTube en URL embebible ── */
function ytEmbedUrl(url) {
  if (!url) return null;
  const m = url.match(/(?:youtu\.be\/|v=|\/embed\/)([A-Za-z0-9_-]{6,})/);
  if (!m) return null;
  const id = m[1];
  // rel=0 (sin sugerencias de otros canales), modestbranding (logo discreto),
  // playsinline (no fullscreen forzado), iv_load_policy=3 (sin anotaciones).
  return `https://www.youtube-nocookie.com/embed/${id}?rel=0&modestbranding=1&playsinline=1&iv_load_policy=3`;
}

/* ═══════════════════════════════════════════════════════════
   LOGIN
   ═══════════════════════════════════════════════════════════ */
const MiembrosLogin = ({ setPage }) => {
  const { t, lang } = useLang();
  const [correo, setCorreo] = React.useState('');
  const [err, setErr] = React.useState('');
  const [sent, setSent] = React.useState(false);
  const [busy, setBusy] = React.useState(false);

  const submit = async (e) => {
    if (e) e.preventDefault();
    setErr('');
    const c = correo.trim().toLowerCase();
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(c)) { setErr(t('Escribe el correo registrado de tu colegio.', 'Enter your school’s registered email.')); return; }
    setBusy(true);
    try {
      const r = await fetch(`${MIEMBROS_API}/login.php`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'include',
        body: JSON.stringify({ correo: c }),
      });
      const data = await r.json().catch(() => ({ ok: false }));
      if (data.ok && data.found) {
        setSent(true);
      } else if (data.ok && data.found === false) {
        setErr(t('Este correo no está registrado como colegio miembro. Verifica que sea el correo de contacto de tu colegio, o escríbenos a contacto@lpdebate.org para registrarlo.', 'This email isn’t registered to a member school. Make sure it’s your school’s contact email, or write to contacto@lpdebate.org to register it.'));
      } else if (data.error === 'rate_limited') {
        setErr(t('Demasiados intentos seguidos. Espera unos minutos y vuelve a intentar.', 'Too many attempts in a row. Please wait a few minutes and try again.'));
      } else if (data.error === 'datos_no_disponibles') {
        setErr(t('No pudimos consultar el registro de colegios en este momento. Intenta de nuevo en unos minutos.', 'We couldn’t check the school registry right now. Please try again in a few minutes.'));
      } else if (data.error === 'mail_failed') {
        setErr(t('No pudimos enviar el correo. Intenta de nuevo o escríbenos a contacto@lpdebate.org.', 'We couldn’t send the email. Try again or write to contacto@lpdebate.org.'));
      } else {
        setErr(t('No pudimos procesar la solicitud. Intenta de nuevo o escríbenos a contacto@lpdebate.org.', 'We couldn’t process your request. Try again or write to contacto@lpdebate.org.'));
      }
    } catch (e2) {
      setErr(t('No pudimos conectar con el servidor. Revisa tu conexión o escríbenos a contacto@lpdebate.org.', 'We couldn’t reach the server. Check your connection or write to contacto@lpdebate.org.'));
    } finally {
      setBusy(false);
    }
  };

  return (
    <section style={{ minHeight: '78vh', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '64px 24px', background: 'var(--bg-alt)' }}>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 0, maxWidth: 880, width: '100%', background: 'var(--bg)', border: '1px solid var(--line)' }}>
        {/* Panel izquierdo — branding */}
        <div style={{ background: 'var(--ink)', color: '#fff', padding: 48, display: 'flex', flexDirection: 'column', justifyContent: 'space-between', position: 'relative', overflow: 'hidden' }}>
          <div aria-hidden="true" style={{ position: 'absolute', top: -40, right: -40, fontFamily: 'var(--serif)', fontSize: 320, lineHeight: 0.78, color: 'rgba(227,6,19,0.18)', fontStyle: 'italic', userSelect: 'none', pointerEvents: 'none' }}>M</div>
          <div style={{ position: 'relative', zIndex: 2 }}>
            <div style={{ fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase', color: 'var(--red)', fontWeight: 700 }}>{t('Área privada', 'Members area')}</div>
            <h1 className="display" style={{ color: '#fff', fontSize: 36, lineHeight: 1.05, marginTop: 12 }}>
              {t(<>Formación para<br />colegios <em className="it">miembros</em></>, <>Training for<br />member <em className="it">schools</em></>)}
            </h1>
          </div>
          <div style={{ position: 'relative', zIndex: 2, fontSize: 14, color: '#B8B8C0', lineHeight: 1.55 }}>
            {t('Plataforma de capacitación continua incluida en la membresía: seminarios, talleres y rutas de aprendizaje con material descargable.', 'An ongoing training platform included in your membership: seminars, workshops and learning tracks with downloadable materials.')}
          </div>
        </div>

        {/* Panel derecho — form de correo (magic link) */}
        {sent
          ? <div style={{ padding: 48, display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
              <div className="kicker" style={{ color: 'var(--red)', marginBottom: 12 }}>{t('Revisa tu correo', 'Check your inbox')}</div>
              <h2 className="display" style={{ fontSize: 28, lineHeight: 1.1, marginBottom: 12 }}>{t('Enlace en camino ✓', 'Link on its way ✓')}</h2>
              <p style={{ fontSize: 14, color: 'var(--ink-2)', lineHeight: 1.6 }}>
                {t(<>Enviamos un enlace de acceso a <strong>{correo.trim().toLowerCase()}</strong>.
                Ábrelo en este dispositivo y entrarás directo al área de miembros.</>, <>We sent an access link to <strong>{correo.trim().toLowerCase()}</strong>.
                Open it on this device and you’ll go straight to the members area.</>)}
              </p>
              <p style={{ fontSize: 13, color: 'var(--mute)', lineHeight: 1.55, marginTop: 14 }}>
                {t('¿No llega? Revisa la carpeta de spam, o escríbenos a contacto@lpdebate.org.', 'Didn’t get it? Check your spam folder, or write to contacto@lpdebate.org.')}
              </p>
              <button type="button" onClick={() => { setSent(false); setErr(''); }} className="btn btn-link" style={{ fontSize: 13, marginTop: 24, alignSelf: 'flex-start' }}>
                ← {t('Usar otro correo', 'Use a different email')}
              </button>
            </div>
          : <form onSubmit={submit} style={{ padding: 48 }}>
              <div className="kicker" style={{ color: 'var(--red)', marginBottom: 12 }}>{t('Ingreso', 'Log in')}</div>
              <h2 className="display" style={{ fontSize: 28, lineHeight: 1.1, marginBottom: 8 }}>{t('Entra con tu correo', 'Log in with your email')}</h2>
              <p style={{ fontSize: 13, color: 'var(--ink-2)', lineHeight: 1.55, marginBottom: 24 }}>
                {t('Sin contraseñas: escribe el correo registrado de tu colegio y te enviamos un enlace de acceso. La sesión dura 30 días en este navegador.', 'No passwords: enter your school’s registered email and we’ll send you an access link. Your session stays active for 30 days in this browser.')}
              </p>

              <label style={{ display: 'block', fontSize: 11, fontFamily: 'var(--mono)', letterSpacing: '0.1em', textTransform: 'uppercase', color: 'var(--mute)', marginBottom: 6 }}>{t('Correo del colegio', 'School email')}</label>
              <input
                className="input"
                type="email"
                value={correo}
                onChange={(e) => { setCorreo(e.target.value); setErr(''); }}
                autoFocus
                autoComplete="email"
                placeholder={t('direccion@tucolegio.edu.pe', 'office@yourschool.edu.pe')}
                style={{ width: '100%', marginBottom: err ? 8 : 20 }}
              />

              {err && <div style={{ fontSize: 13, color: 'var(--red)', marginBottom: 12, lineHeight: 1.5 }}>{err}</div>}

              <button type="submit" className="btn btn-red" disabled={busy} style={{ width: '100%', justifyContent: 'center' }}>
                {busy ? t('Enviando…', 'Sending…') : <>{t('Enviarme el enlace', 'Send me the link')} <Icon name="arrow" size={14} /></>}
              </button>

              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 24, paddingTop: 16, borderTop: '1px solid var(--line)' }}>
                <button type="button" onClick={() => setPage && setPage('admision')} className="btn btn-link" style={{ fontSize: 13 }}>
                  {t('¿Cómo ser miembro?', 'How to become a member')}
                </button>
                <button type="button" onClick={() => setPage && setPage('presentacion')} className="btn btn-link" style={{ fontSize: 13, color: 'var(--mute)' }}>
                  {t('Volver al inicio', 'Back to home')}
                </button>
              </div>
            </form>}
      </div>
    </section>
  );
};

/* ═══════════════════════════════════════════════════════════
   DASHBOARD — grilla de sesiones con filtros
   ═══════════════════════════════════════════════════════════ */
const FILTERS = [
  { key: 'area', label: 'Tema', en: 'Topic' },
  { key: 'level', label: 'Nivel', en: 'Level' },
  { key: 'path', label: 'Ruta', en: 'Track' },
];

const MiembrosDashboard = ({ sess, onOpen, onLogout }) => {
  const { t, lang } = useLang();
  const D = window.LPDE_DATA;
  const M = (D && D.miembros) || { areas: [], levels: [], paths: [] };
  const { sessions, status } = useMiembrosSessions();
  const [filterKey, setFilterKey] = React.useState('area');
  const [filterValue, setFilterValue] = React.useState('Todos');
  const [query, setQuery] = React.useState('');

  // Valores disponibles para el filtro: catálogo base + cualquier valor extra del Sheet
  const collectValues = (key, base) => {
    const fromSessions = sessions.map((s) => s[key]).filter(Boolean);
    return ['Todos', ...Array.from(new Set([...(base || []), ...fromSessions]))];
  };
  const valuesByKey = {
    area: collectValues('area', M.areas),
    level: collectValues('level', M.levels),
    path: collectValues('path', M.paths),
  };

  const filtered = sessions.filter((s) => {
    const okFilter = filterValue === 'Todos' || s[filterKey] === filterValue;
    const q = query.trim().toLowerCase();
    const okQuery = q === '' || (s.title + ' ' + (s.summary || '') + ' ' + (s.speaker || '')).toLowerCase().includes(q);
    return okFilter && okQuery;
  });

  return (
    <>
      {/* Barra de sesión */}
      <section style={{ background: 'var(--ink)', color: '#fff', borderBottom: '1px solid #2A2A30' }}>
        <div className="shell" style={{ display: 'flex', alignItems: 'center', gap: 16, padding: '18px 0', flexWrap: 'wrap' }}>
          <div>
            <div style={{ fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--red)' }}>{t('Área privada · Colegios miembros', 'Members area · Member schools')}</div>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 22, marginTop: 4 }}>
              {t('Hola,', 'Hello,')} <em className="it" style={{ color: '#fff' }}>{sess.user}</em>
            </div>
          </div>
          <div style={{ flex: 1 }} />
          <button className="btn btn-light" style={{ padding: '8px 14px' }} onClick={onLogout}>{t('Cerrar sesión', 'Log out')}</button>
        </div>
      </section>

      {/* Header */}
      <section style={{ paddingTop: 56, paddingBottom: 24, borderBottom: '1px solid var(--line)' }}>
        <div className="shell">
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'end', flexWrap: 'wrap', gap: 32 }}>
            <div className="reveal">
              <span className="eyebrow">{t('Capacitación', 'Training')}</span>
              <h1 className="display" style={{ fontSize: 'clamp(40px, 6vw, 84px)', marginTop: 16 }}>
                {t(<>Sesiones <em className="it">disponibles</em></>, <>Available <em className="it">sessions</em></>)}
              </h1>
              <p style={{ fontSize: 16, color: 'var(--ink-2)', lineHeight: 1.55, marginTop: 12, maxWidth: 560 }}>
                {t('Material exclusivo para el cuerpo docente del colegio miembro. Cada sesión incluye video y descargables.', 'Exclusive material for your member school’s teaching staff. Each session includes a video and downloads.')}
              </p>
            </div>
            <div className="reveal d1" style={{ display: 'flex', alignItems: 'center', gap: 12, background: 'var(--bg-alt)', padding: '8px 8px 8px 18px', borderRadius: 999, border: '1px solid var(--line)' }}>
              <Icon name="search" size={16} />
              <input
                className="input"
                placeholder={t('Buscar sesión…', 'Search sessions…')}
                value={query}
                onChange={(e) => setQuery(e.target.value)}
                style={{ border: 'none', background: 'transparent', padding: '6px 0', width: 220 }}
              />
            </div>
          </div>
        </div>
      </section>

      {/* Barras de filtro */}
      <section style={{ padding: '20px 0', borderBottom: '1px solid var(--line)', background: 'var(--bg-alt)' }}>
        <div className="shell" style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
            <span className="kicker" style={{ marginRight: 6 }}>{t('Agrupar por', 'Group by')}</span>
            {FILTERS.map((f) => (
              <button key={f.key}
                onClick={() => { setFilterKey(f.key); setFilterValue('Todos'); }}
                style={{
                  padding: '6px 14px', borderRadius: 999,
                  background: filterKey === f.key ? 'var(--ink)' : 'transparent',
                  color: filterKey === f.key ? '#fff' : 'var(--ink-soft)',
                  border: '1px solid ' + (filterKey === f.key ? 'var(--ink)' : 'var(--line)'),
                  fontSize: 12, fontWeight: 600, fontFamily: 'var(--sans)', cursor: 'pointer', transition: 'all 180ms',
                }}>{t(f.label, f.en)}</button>
            ))}
          </div>
          <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
            {(valuesByKey[filterKey] || []).map((v) => (
              <button key={v}
                onClick={() => setFilterValue(v)}
                style={{
                  padding: '6px 12px', borderRadius: 999,
                  background: filterValue === v ? 'var(--red)' : 'var(--bg)',
                  color: filterValue === v ? '#fff' : 'var(--ink-soft)',
                  border: '1px solid ' + (filterValue === v ? 'var(--red)' : 'var(--line)'),
                  fontSize: 12, fontWeight: 500, fontFamily: 'var(--sans)', cursor: 'pointer', transition: 'all 180ms',
                }}>{v === 'Todos' ? t('Todos', 'All') : v}</button>
            ))}
          </div>
        </div>
      </section>

      {/* Grid de sesiones */}
      <section className="section">
        <div className="shell">
          {filtered.length === 0
            ? <div style={{ textAlign: 'center', padding: '64px 24px', border: '1px dashed var(--line-strong)', background: 'var(--bg-alt)' }}>
                <p style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 22, color: 'var(--mute)' }}>
                  {t('No hay sesiones para tu búsqueda.', 'No sessions match your search.')}
                </p>
              </div>
            : <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))', gap: 20 }}>
                {filtered.map((s, i) => (
                  <article key={s.id} className={`reveal d${i % 4 + 1}`}
                    onClick={() => onOpen(s)}
                    style={{
                      background: 'var(--bg)', border: '1px solid var(--line)',
                      cursor: 'pointer', display: 'flex', flexDirection: 'column',
                      transition: 'all 280ms ease', overflow: 'hidden',
                    }}
                    onMouseEnter={(e) => { e.currentTarget.style.transform = 'translateY(-4px)'; e.currentTarget.style.boxShadow = '0 16px 40px rgba(0,0,0,0.08)'; e.currentTarget.style.borderColor = 'var(--red)'; }}
                    onMouseLeave={(e) => { e.currentTarget.style.transform = 'translateY(0)'; e.currentTarget.style.boxShadow = 'none'; e.currentTarget.style.borderColor = 'var(--line)'; }}
                  >
                    {/* Tag bar */}
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '14px 20px', background: 'var(--ink)', color: '#fff' }}>
                      <span style={{ padding: '3px 9px', borderRadius: 3, background: 'var(--red)', color: '#fff', fontSize: 9, fontWeight: 700, letterSpacing: '0.14em', fontFamily: 'var(--mono)' }}>
                        {s.kind ? s.kind.toUpperCase() : t('SESIÓN', 'SESSION')}
                      </span>
                      <span style={{ fontFamily: 'var(--mono)', fontSize: 11, color: '#B8B8C0', letterSpacing: '0.05em' }}>{s.date}</span>
                      <span style={{ marginLeft: 'auto', fontFamily: 'var(--mono)', fontSize: 11, color: '#9C9AA0' }}>{s.duration}</span>
                    </div>

                    {/* Body */}
                    <div style={{ padding: '20px 22px 24px', display: 'flex', flexDirection: 'column', flex: 1, gap: 12 }}>
                      <h3 className="display" style={{ fontSize: 22, lineHeight: 1.15 }}>{s.title}</h3>
                      {s.speaker && (
                        <div style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 15, color: 'var(--ink-2)' }}>
                          {t('con', 'with')} {s.speaker}
                        </div>
                      )}
                      <p style={{ fontSize: 14, color: 'var(--ink-soft)', lineHeight: 1.55, flex: 1 }}>
                        {(s.summary || '').slice(0, 130)}{(s.summary || '').length > 130 ? '…' : ''}
                      </p>
                      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, paddingTop: 12, borderTop: '1px solid var(--line)' }}>
                        {[s.area, s.level, s.path].filter(Boolean).map((t, j) => (
                          <span key={j} style={{ padding: '3px 8px', background: 'var(--bg-alt)', fontSize: 10, fontFamily: 'var(--mono)', letterSpacing: '0.06em', color: 'var(--ink-2)' }}>{t}</span>
                        ))}
                      </div>
                      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', paddingTop: 10 }}>
                        <span className="kicker" style={{ color: 'var(--red)' }}>{t('Abrir sesión', 'Open session')} →</span>
                        <span style={{ display: 'flex', gap: 12, fontSize: 11, color: 'var(--mute)', fontFamily: 'var(--mono)' }}>
                          {s.video && <span title={t('Video disponible', 'Video available')}>▶ Video</span>}
                          {Array.isArray(s.materials) && s.materials.length > 0 && <span title={t('Material descargable', 'Downloadable material')}>⬇ {s.materials.length} material{s.materials.length > 1 ? t('es', 's') : ''}</span>}
                        </span>
                      </div>
                    </div>
                  </article>
                ))}
              </div>
          }

          <p style={{ fontSize: 12, color: 'var(--mute)', marginTop: 32, textAlign: 'center', fontFamily: 'var(--mono)', letterSpacing: '0.04em' }}>
            {filtered.length} {t('de', 'of')} {sessions.length} {t('sesiones', 'sessions')} · {status === 'live' ? t('sincronizado con el Sheet', 'live data') : status === 'loading' ? t('cargando…', 'loading…') : t('modo offline (snapshot local)', 'offline mode (local snapshot)')}
          </p>
        </div>
      </section>
    </>
  );
};

/* ═══════════════════════════════════════════════════════════
   VISTA DE SESIÓN — video + descargables
   ═══════════════════════════════════════════════════════════ */
const MiembrosSessionView = ({ session, sess, onBack }) => {
  const { t, lang } = useLang();
  const embed = ytEmbedUrl(session.video);

  // Bloquear menú contextual sobre el reproductor (deterrent)
  const blockContext = (e) => { e.preventDefault(); return false; };

  return (
    <>
      {/* Barra de sesión */}
      <section style={{ background: 'var(--ink)', color: '#fff', borderBottom: '1px solid #2A2A30' }}>
        <div className="shell" style={{ display: 'flex', alignItems: 'center', gap: 16, padding: '14px 0', flexWrap: 'wrap' }}>
          <button onClick={onBack} className="btn btn-light" style={{ padding: '6px 14px' }}>
            ← {t('Volver al dashboard', 'Back to dashboard')}
          </button>
          <div style={{ flex: 1 }} />
          <span style={{ fontFamily: 'var(--mono)', fontSize: 11, color: '#9C9AA0', letterSpacing: '0.06em' }}>
            {t('Sesión iniciada como', 'Logged in as')} <strong style={{ color: '#fff' }}>{sess.user}</strong>
          </span>
        </div>
      </section>

      {/* Encabezado de sesión */}
      <section style={{ paddingTop: 48, paddingBottom: 16 }}>
        <div className="shell">
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 16, flexWrap: 'wrap' }}>
            <span style={{ padding: '3px 9px', borderRadius: 3, background: 'var(--red)', color: '#fff', fontSize: 9, fontWeight: 700, letterSpacing: '0.14em', fontFamily: 'var(--mono)' }}>
              {(session.kind || t('SESIÓN', 'SESSION')).toUpperCase()}
            </span>
            <span className="kicker">{session.date}</span>
            <span className="kicker" style={{ color: 'var(--mute)' }}>· {session.duration}</span>
          </div>
          <h1 className="display" style={{ fontSize: 'clamp(36px, 5vw, 64px)', lineHeight: 1.05, maxWidth: '24ch' }}>
            {session.title}
          </h1>
          {session.speaker && (
            <p style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 22, color: 'var(--ink-2)', marginTop: 16 }}>
              {t('con', 'with')} {session.speaker}
            </p>
          )}
        </div>
      </section>

      {/* Layout principal: video + sidebar de materiales */}
      <section className="section" style={{ paddingTop: 32 }}>
        <div className="shell" style={{ display: 'grid', gridTemplateColumns: '2.4fr 1fr', gap: 40, alignItems: 'start' }}>
          {/* Video con watermark */}
          <div>
            {embed
              ? <div onContextMenu={blockContext}
                  style={{
                    position: 'relative', aspectRatio: '16/9', width: '100%',
                    background: '#000', border: '1px solid var(--line)', overflow: 'hidden',
                  }}>
                  <iframe
                    src={embed}
                    title={session.title}
                    allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                    allowFullScreen
                    referrerPolicy="strict-origin-when-cross-origin"
                    style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', border: 0 }}
                  />
                  {/* Watermark — esquina inferior derecha */}
                  <div aria-hidden="true" style={{
                    position: 'absolute', bottom: 14, right: 16,
                    background: 'rgba(0,0,0,0.45)', color: 'rgba(255,255,255,0.78)',
                    padding: '4px 10px', borderRadius: 4,
                    fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.12em',
                    textTransform: 'uppercase', pointerEvents: 'none', userSelect: 'none', zIndex: 2,
                  }}>
                    LPDE · {sess.user}
                  </div>
                </div>
              : <div style={{ aspectRatio: '16/9', background: 'var(--bg-alt)', border: '1px dashed var(--line-strong)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--mute)', fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 22 }}>
                  {t('Sin video disponible', 'No video available')}
                </div>}

            {session.summary && (
              <div style={{ marginTop: 32 }}>
                <span className="eyebrow">{t('Resumen', 'Summary')}</span>
                <p style={{ fontSize: 17, lineHeight: 1.7, color: 'var(--ink-soft)', marginTop: 14 }}>
                  {session.summary}
                </p>
              </div>
            )}

            {/* Tags */}
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, marginTop: 28, paddingTop: 20, borderTop: '1px solid var(--line)' }}>
              {[
                { label: t('Tema', 'Topic'), value: session.area },
                { label: t('Nivel', 'Level'), value: session.level },
                { label: t('Ruta', 'Track'), value: session.path },
              ].filter((t) => t.value).map((t, j) => (
                <div key={j} style={{ padding: '8px 14px', background: 'var(--bg-alt)', border: '1px solid var(--line)' }}>
                  <div style={{ fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--mute)' }}>{t.label}</div>
                  <div style={{ fontFamily: 'var(--serif)', fontSize: 16, color: 'var(--ink)', marginTop: 2 }}>{t.value}</div>
                </div>
              ))}
            </div>
          </div>

          {/* Sidebar — material descargable */}
          <aside style={{ position: 'sticky', top: 'calc(var(--nav-h) + 24px)' }}>
            <div style={{ background: 'var(--bg)', border: '1px solid var(--line)', padding: 24 }}>
              <div className="kicker" style={{ color: 'var(--red)', marginBottom: 16 }}>{t('Material complementario', 'Supporting materials')}</div>
              {Array.isArray(session.materials) && session.materials.length > 0
                ? <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                    {session.materials.map((m, i) => (
                      <a key={i} href={m.url} target="_blank" rel="noopener"
                        style={{ display: 'flex', alignItems: 'center', gap: 14, padding: '14px 16px', background: 'var(--bg-alt)', border: '1px solid var(--line)', textDecoration: 'none', color: 'var(--ink)', transition: 'all 200ms' }}
                        onMouseEnter={(e) => { e.currentTarget.style.borderColor = 'var(--red)'; e.currentTarget.style.background = 'var(--bg)'; }}
                        onMouseLeave={(e) => { e.currentTarget.style.borderColor = 'var(--line)'; e.currentTarget.style.background = 'var(--bg-alt)'; }}
                      >
                        <div style={{ width: 36, height: 36, background: 'var(--red)', color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                          <Icon name="download" size={16} />
                        </div>
                        <div style={{ flex: 1, minWidth: 0 }}>
                          <div style={{ fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.1em', textTransform: 'uppercase', color: 'var(--mute)' }}>{m.kind}</div>
                          <div style={{ fontFamily: 'var(--serif)', fontSize: 15, color: 'var(--ink)', marginTop: 2, lineHeight: 1.25 }}>{m.label || m.kind}</div>
                        </div>
                        <Icon name="arrow-up-right" size={14} />
                      </a>
                    ))}
                  </div>
                : <p style={{ fontSize: 13, color: 'var(--mute)', fontStyle: 'italic' }}>
                    {t('Aún no se ha publicado material para esta sesión.', 'No materials have been published for this session yet.')}
                  </p>}
            </div>

            {/* Disclaimer privacidad */}
            <div style={{ marginTop: 16, padding: '16px 18px', background: 'var(--bg-alt)', border: '1px solid var(--line)', borderLeft: '3px solid var(--red)' }}>
              <div className="kicker" style={{ marginBottom: 6 }}>{t('Aviso de uso', 'Usage notice')}</div>
              <p style={{ fontSize: 12, color: 'var(--ink-2)', lineHeight: 1.55, margin: 0 }}>
                {t('Los videos son de uso interno del colegio miembro. El material complementario puede compartirse con tu equipo docente, citando a la LPDE como fuente.', 'Videos are for internal use within your member school. Supporting materials may be shared with your teaching staff, crediting LPDE as the source.')}
              </p>
            </div>
          </aside>
        </div>
      </section>
    </>
  );
};

/* ═══════════════════════════════════════════════════════════
   ENTRY — orquesta login / dashboard / sesión
   ═══════════════════════════════════════════════════════════ */
const ColegiosMiembrosPage = ({ setPage }) => {
  const { t, lang } = useLang();
  const [sess, setSess] = React.useState(null);          // {user, cid, correo}
  const [checking, setChecking] = React.useState(true);  // consultando session.php
  const [openSession, setOpenSession] = React.useState(null);

  // Al montar: ¿hay cookie de sesión válida?
  React.useEffect(() => {
    let cancelled = false;
    fetch(`${MIEMBROS_API}/session.php`, { cache: 'no-store', credentials: 'include' })
      .then((r) => r.ok ? r.json() : Promise.reject('http ' + r.status))
      .then((data) => {
        if (cancelled) return;
        if (data.ok && data.colegio) {
          setSess({ user: data.colegio.nombre || data.correo, cid: data.colegio.id, correo: data.correo });
        }
      })
      .catch(() => {})
      .finally(() => { if (!cancelled) setChecking(false); });
    return () => { cancelled = true; };
  }, []);

  const logout = () => {
    fetch(`${MIEMBROS_API}/logout.php`, { method: 'POST', credentials: 'include' }).catch(() => {});
    setSess(null);
    setOpenSession(null);
  };
  const openSess = (s) => { setOpenSession(s); window.scrollTo({ top: 0, behavior: 'smooth' }); };
  const backToDash = () => { setOpenSession(null); window.scrollTo({ top: 0, behavior: 'smooth' }); };

  if (checking) {
    return (
      <Page screen="Colegios Miembros · Acceso">
        <section style={{ minHeight: '60vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--bg-alt)' }}>
          <p style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 22, color: 'var(--mute)' }}>{t('Verificando acceso…', 'Verifying access…')}</p>
        </section>
      </Page>
    );
  }

  if (!sess) {
    return (
      <Page screen="Colegios Miembros · Acceso">
        <MiembrosLogin setPage={setPage} />
      </Page>
    );
  }

  if (openSession) {
    return (
      <Page screen="Colegios Miembros · Sesión">
        <MiembrosSessionView session={openSession} sess={sess} onBack={backToDash} />
      </Page>
    );
  }

  return (
    <Page screen="Colegios Miembros · Dashboard">
      <MiembrosDashboard sess={sess} onOpen={openSess} onLogout={logout} />
    </Page>
  );
};

Object.assign(window, { ColegiosMiembrosPage });
