/* ============================================================
   Panel de producción — diseño 100% del ZIP, datos de Firebase
   ============================================================ */

const LOGO = 'assets/guitarfabrik-logo.png';

// ── helpers ──────────────────────────────────────────────────
function getThumb(url) {
  const m = url?.match(/(?:youtu\.be\/|youtube\.com\/(?:watch\?v=|embed\/|shorts\/))([a-zA-Z0-9_-]{11})/);
  return m ? `https://img.youtube.com/vi/${m[1]}/mqdefault.jpg` : null;
}
function getWatch(url) {
  const m = url?.match(/(?:youtu\.be\/|youtube\.com\/(?:watch\?v=|embed\/|shorts\/))([a-zA-Z0-9_-]{11})/);
  return m ? `https://www.youtube.com/watch?v=${m[1]}` : url;
}

// ── shared sub-components (same as ZIP) ──────────────────────
function Avatar({ letter, size = 48 }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%', flexShrink: 0,
      background: 'radial-gradient(circle at 35% 30%, #e7cf86, #c9a84c 60%, #9c7e34)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontWeight: 800, color: '#1c1a16', fontSize: size * 0.4,
    }}>{letter}</div>
  );
}

function StatusBadge({ done }) {
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 5,
      fontSize: 11, fontWeight: 700, padding: '4px 10px', borderRadius: 999,
      background: done ? 'rgba(92,184,95,.13)' : 'var(--gold-soft)',
      border: `1px solid ${done ? 'rgba(92,184,95,.4)' : 'var(--gold-line)'}`,
      color: done ? 'var(--success)' : 'var(--gold)', whiteSpace: 'nowrap',
    }}>
      {done ? <><Icon name="check" size={12} color="var(--success)" /> Cuestionario</> : <><Icon name="clock" size={12} /> Pendiente</>}
    </span>
  );
}

function QAns({ label, value }) {
  return (
    <div style={{ background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 11, padding: '10px 13px' }}>
      <div style={{ fontSize: 10.5, color: 'var(--muted)', fontWeight: 700, letterSpacing: .3, marginBottom: 3 }}>{label.toUpperCase()}</div>
      <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--text)' }}>{value}</div>
    </div>
  );
}

// ── Login ────────────────────────────────────────────────────
function WebLogin({ onLogin, deniedMsg }) {
  const [email, setEmail] = React.useState('');
  const [pass, setPass] = React.useState('');
  const [err, setErr] = React.useState('');
  const [loading, setLoading] = React.useState(false);

  const handleLogin = async (e) => {
    e.preventDefault();
    setErr(''); setLoading(true);
    try {
      await window._fb.signInWithEmailAndPassword(window._auth, email, pass);
      onLogin();
    } catch {
      setErr('Email o contraseña incorrectos');
    } finally {
      setLoading(false);
    }
  };

  const shownError = err || deniedMsg;

  return (
    <div style={{ width: '100%', minHeight: '100vh', background: 'radial-gradient(700px 400px at 50% 0%, #2c2925 0%, transparent 60%), var(--bg)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      <div className="card" style={{ width: 380, padding: 36 }}>
        <div style={{ display: 'flex', justifyContent: 'center', marginBottom: 8 }}>
          <img src={LOGO} alt="GuitarFabrik" style={{ height: 34 }} />
        </div>
        <div className="brand-academy" style={{ textAlign: 'center', marginBottom: 6 }}>ACADEMY</div>
        <div style={{ textAlign: 'center', fontSize: 13.5, fontStyle: 'italic', color: 'var(--text-2)', marginBottom: 26 }}>Panel del profesor</div>
        <form className="col" style={{ gap: 13 }} onSubmit={handleLogin}>
          <div>
            <label className="web-label">Email</label>
            <input className="web-input" type="email" placeholder="profesor@guitarfabrik.com" value={email} onChange={e => setEmail(e.target.value)} required />
          </div>
          <div>
            <label className="web-label">Contraseña</label>
            <input className="web-input" type="password" placeholder="••••••••" value={pass} onChange={e => setPass(e.target.value)} required />
          </div>
          {shownError && <div style={{ fontSize: 13, color: '#f44336', background: 'rgba(244,67,54,.1)', borderRadius: 8, padding: '8px 12px' }}>⚠ {shownError}</div>}
          <button className="btn-action" type="submit" disabled={loading} style={{ marginTop: 8 }}>
            {loading ? 'Entrando…' : 'Entrar'}
          </button>
        </form>
      </div>
    </div>
  );
}

// ── Dashboard ────────────────────────────────────────────────
function WebStat({ icon, label, value }) {
  return (
    <div style={{ background: 'var(--card)', border: '1px solid var(--gold-line)', borderRadius: 16, padding: 24 }}>
      <div style={{ width: 46, height: 46, borderRadius: 13, background: 'var(--gold-soft)', border: '1px solid var(--gold-line)', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 16 }}>
        <Icon name={icon} size={23} color="var(--gold)" />
      </div>
      <div style={{ fontSize: 38, fontWeight: 800, color: 'var(--gold)', lineHeight: 1, marginBottom: 6 }}>{value}</div>
      <div style={{ fontSize: 14, color: 'var(--muted)' }}>{label}</div>
    </div>
  );
}

function WebDashboard() {
  const [stats, setStats] = React.useState({ students: '…', videos: '…', pending: '…' });
  const [videos, setVideos] = React.useState([]);

  React.useEffect(() => {
    const { collection, getDocs, query, where } = window._fb;
    const db = window._db;
    Promise.all([
      getDocs(query(collection(db,'users'), where('role','==','student'))),
      getDocs(collection(db,'videos')),
      getDocs(query(collection(db,'users'), where('role','==','student'), where('questionnaireCompleted','==',false))),
    ]).then(([s,v,p]) => {
      const vids = v.docs.map(d=>({id:d.id,...d.data()}))
        .sort((a,b)=>(b.createdAt||'').localeCompare(a.createdAt||''));
      setStats({ students: s.size, videos: v.size, pending: p.size });
      setVideos(vids.slice(0,5));
    });
  }, []);

  return (
    <div>
      <h1 style={{ fontSize: 28, fontWeight: 800, marginBottom: 4 }}>Dashboard</h1>
      <p style={{ color: 'var(--muted)', fontSize: 14.5, marginBottom: 28 }}>Resumen de tu academia.</p>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 18, marginBottom: 36 }}>
        <WebStat icon="people" label="Alumnos" value={stats.students} />
        <WebStat icon="video" label="Vídeos subidos" value={stats.videos} />
        <WebStat icon="clipboard" label="Sin cuestionario" value={stats.pending} />
      </div>
      <h2 style={{ fontSize: 19, fontWeight: 700, marginBottom: 16 }}>Últimas clases subidas</h2>
      <div className="col" style={{ gap: 11 }}>
        {videos.length === 0
          ? <div style={{ color: 'var(--muted)', padding: '40px 0', textAlign: 'center' }}>Aún no has subido ningún vídeo</div>
          : videos.map(v => {
            const thumb = getThumb(v.url);
            return (
              <div key={v.id} style={{ background: 'var(--card)', border: '1px solid var(--border)', borderRadius: 12, padding: '12px 16px', display: 'flex', alignItems: 'center', gap: 16 }}>
                {thumb && (
                  <div style={{ width: 96, height: 54, borderRadius: 8, overflow: 'hidden', flexShrink: 0, position: 'relative', background: '#000' }}>
                    <img src={thumb} className="cover" alt="" style={{ filter: 'brightness(.8)' }} />
                    <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                      <Icon name="play" size={18} color="#fff" />
                    </div>
                  </div>
                )}
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontWeight: 700, fontSize: 15 }}>{v.title}</div>
                  <div style={{ color: 'var(--muted)', fontSize: 13, marginTop: 3 }}>
                    {v.week ? `Semana ${v.week} · ` : ''}{v.description?.slice(0,70)}{v.description?.length > 70 ? '…' : ''}
                  </div>
                </div>
                <div style={{ color: 'var(--muted)', fontSize: 13, whiteSpace: 'nowrap' }}>
                  {v.createdAt ? new Date(v.createdAt).toLocaleDateString('es-ES',{day:'numeric',month:'short',year:'numeric'}) : ''}
                </div>
              </div>
            );
          })
        }
      </div>
    </div>
  );
}

// ── Videos ───────────────────────────────────────────────────
function WebVideos() {
  const [videos, setVideos] = React.useState([]);
  const [form, setForm] = React.useState({ title: '', url: '', desc: '', notes: '' });
  const [saving, setSaving] = React.useState(false);
  const [err, setErr] = React.useState('');
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const valid = /youtu/.test(form.url);
  const thumb = getThumb(form.url);

  const load = () => {
    const { collection, getDocs } = window._fb;
    getDocs(collection(window._db,'videos')).then(snap => {
      setVideos(snap.docs.map(d=>({id:d.id,...d.data()}))
        .sort((a,b)=>(b.createdAt||'').localeCompare(a.createdAt||'')));
    });
  };
  React.useEffect(load, []);

  const handleAdd = async (e) => {
    e.preventDefault();
    setErr('');
    if (!form.title.trim() || !valid) { setErr('Título y URL de YouTube son obligatorios'); return; }
    setSaving(true);
    try {
      const { collection, addDoc } = window._fb;
      await addDoc(collection(window._db,'videos'), {
        title: form.title.trim(), url: form.url.trim(),
        description: form.desc.trim(), notes: form.notes.trim(),
        createdAt: new Date().toISOString(),
        week: Math.ceil((new Date() - new Date(new Date().getFullYear(),0,1))/(7*24*60*60*1000)),
      });
      setForm({ title:'', url:'', desc:'', notes:'' });
      load();
    } catch(e) { setErr('Error: ' + e.message); }
    finally { setSaving(false); }
  };

  const handleDelete = async (v) => {
    if (!confirm(`¿Eliminar "${v.title}"?`)) return;
    const { doc, deleteDoc } = window._fb;
    await deleteDoc(doc(window._db,'videos',v.id));
    setVideos(vs => vs.filter(x => x.id !== v.id));
  };

  return (
    <div>
      <h1 style={{ fontSize: 28, fontWeight: 800, marginBottom: 4 }}>Vídeos / Clases</h1>
      <p style={{ color: 'var(--muted)', fontSize: 14.5, marginBottom: 28 }}>
        Sube tus vídeos a YouTube como <strong style={{ color: 'var(--gold)' }}>No listado</strong> y pega el enlace aquí.
      </p>
      <div style={{ display: 'grid', gridTemplateColumns: '380px 1fr', gap: 28, alignItems: 'start' }}>
        {/* Form */}
        <div className="card" style={{ padding: 24 }}>
          <div style={{ fontSize: 16, fontWeight: 700, marginBottom: 18 }}>Nueva clase</div>
          <form className="col" style={{ gap: 15 }} onSubmit={handleAdd}>
            <div>
              <label className="web-label">Título</label>
              <input className="web-input" placeholder="Ej: Técnica de picado — Farruca" value={form.title} onChange={e=>set('title',e.target.value)} />
            </div>
            <div>
              <label className="web-label">URL de YouTube</label>
              <div className="field">
                <Icon name="link" size={18} />
                <input placeholder="https://youtu.be/…" value={form.url} onChange={e=>set('url',e.target.value)} />
              </div>
              {form.url && (
                <div className="row" style={{ alignItems:'center', gap:6, marginTop:8, fontSize:12.5, color: valid ? 'var(--success)' : 'var(--muted)' }}>
                  <Icon name={valid ? 'checkCircle' : 'clock'} size={15} color={valid ? 'var(--success)' : 'var(--muted)'} />
                  {valid ? 'URL válida' : 'Introduce un enlace de YouTube'}
                </div>
              )}
              {thumb && (
                <div style={{ marginTop:10, borderRadius:10, overflow:'hidden', position:'relative', aspectRatio:'16/9', background:'#000' }}>
                  <img src={thumb} className="cover" alt="" style={{ filter:'brightness(.7)' }} />
                  <div style={{ position:'absolute', inset:0, display:'flex', alignItems:'center', justifyContent:'center' }}>
                    <Icon name="play" size={30} color="#fff" />
                  </div>
                </div>
              )}
            </div>
            <div>
              <label className="web-label">Descripción</label>
              <textarea className="web-input" rows="3" placeholder="Qué aprende el alumno" value={form.desc} onChange={e=>set('desc',e.target.value)} style={{ resize:'none' }} />
            </div>
            <div>
              <label className="web-label">Notas para el alumno</label>
              <textarea className="web-input" rows="3" placeholder="Ejercicios para practicar…" value={form.notes} onChange={e=>set('notes',e.target.value)} style={{ resize:'none' }} />
            </div>
            {err && <div style={{ fontSize:13, color:'#f44336', background:'rgba(244,67,54,.1)', borderRadius:8, padding:'8px 12px' }}>⚠ {err}</div>}
            <button className="btn-gold" type="submit" disabled={saving || !valid || !form.title.trim()}>
              <Icon name="checkCircle" size={18} color="#1c1a16" /> {saving ? 'Publicando…' : 'Publicar clase'}
            </button>
          </form>
        </div>

        {/* List */}
        <div>
          <div style={{ fontSize:15, fontWeight:700, marginBottom:14, color:'var(--text-2)' }}>Clases publicadas · {videos.length}</div>
          <div className="col" style={{ gap:14 }}>
            {videos.length === 0
              ? <div style={{ color:'var(--muted)', textAlign:'center', padding:'60px 0' }}>Aún no has publicado ninguna clase</div>
              : videos.map(v => {
                const vThumb = getThumb(v.url);
                return (
                  <div key={v.id} className="card" style={{ padding:14, display:'flex', gap:16 }}>
                    <div style={{ width:150, height:84, borderRadius:10, overflow:'hidden', flexShrink:0, position:'relative', background:'#000' }}>
                      {vThumb ? <img src={vThumb} className="cover" alt="" style={{ filter:'brightness(.82)' }} /> : null}
                      <div style={{ position:'absolute', inset:0, display:'flex', alignItems:'center', justifyContent:'center' }}>
                        <Icon name="play" size={24} color="#fff" />
                      </div>
                      {v.week && <span style={{ position:'absolute', top:7, left:7, fontSize:10.5, fontWeight:700, color:'var(--gold)', background:'rgba(0,0,0,.6)', padding:'3px 7px', borderRadius:999 }}>Semana {v.week}</span>}
                    </div>
                    <div style={{ flex:1, minWidth:0, display:'flex', flexDirection:'column' }}>
                      <div style={{ fontWeight:700, fontSize:15.5 }}>{v.title}</div>
                      {v.description && <div style={{ color:'var(--muted)', fontSize:13, margin:'5px 0', lineHeight:1.45 }}>{v.description.slice(0,90)}{v.description.length>90?'…':''}</div>}
                      <div className="row" style={{ alignItems:'center', gap:12, marginTop:'auto' }}>
                        <span style={{ fontSize:12.5, color:'var(--muted)' }}>
                          {v.createdAt ? new Date(v.createdAt).toLocaleDateString('es-ES',{day:'numeric',month:'short',year:'numeric'}) : ''}
                        </span>
                        <div style={{ flex:1 }} />
                        <a href={getWatch(v.url)} target="_blank" rel="noreferrer" style={{ display:'flex', alignItems:'center', gap:6, fontSize:13, fontWeight:600, color:'var(--gold)', padding:'6px 12px', borderRadius:8, border:'1px solid var(--gold-line)', textDecoration:'none' }}>
                          <Icon name="play" size={13} color="var(--gold)" /> Ver
                        </a>
                        <button onClick={()=>handleDelete(v)} style={{ display:'flex', alignItems:'center', gap:6, fontSize:13, fontWeight:600, color:'var(--muted)', padding:'6px 12px', borderRadius:8, border:'1px solid var(--border)' }}>
                          <Icon name="trash" size={13} color="var(--muted)" /> Eliminar
                        </button>
                      </div>
                    </div>
                  </div>
                );
              })
            }
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Alumnos ──────────────────────────────────────────────────
function WebAlumnos() {
  const [students, setStudents] = React.useState([]);
  const [exp, setExp] = React.useState(null);

  React.useEffect(() => {
    const { collection, getDocs, query, where } = window._fb;
    getDocs(query(collection(window._db,'users'), where('role','==','student'))).then(snap => {
      const list = snap.docs.map(d=>({id:d.id,...d.data()}))
        .sort((a,b)=>(b.createdAt||'').localeCompare(a.createdAt||''));
      setStudents(list);
    });
  }, []);

  return (
    <div>
      <h1 style={{ fontSize:28, fontWeight:800, marginBottom:4 }}>Alumnos</h1>
      <p style={{ color:'var(--muted)', fontSize:14.5, marginBottom:28 }}>
        {students.length} alumnos inscritos · pulsa para ver el cuestionario.
      </p>
      <div className="col" style={{ gap:14, maxWidth:760 }}>
        {students.length === 0
          ? <div style={{ color:'var(--muted)', textAlign:'center', padding:'60px 0' }}>Aún no hay alumnos registrados</div>
          : students.map(s => {
            const open = exp === s.id;
            const letter = s.name?.[0]?.toUpperCase() || s.email?.[0]?.toUpperCase() || '?';
            const q = s.questionnaire || {};
            return (
              <div key={s.id} className="card" style={{ overflow:'hidden' }}>
                <button onClick={()=>setExp(open?null:s.id)}
                  style={{ display:'flex', alignItems:'center', gap:16, padding:'16px 20px', width:'100%', textAlign:'left', background:'none', border:'none', cursor:'pointer', color:'var(--text)', fontFamily:'inherit' }}>
                  <Avatar letter={letter} size={48} />
                  <div className="col" style={{ flex:1, minWidth:0 }}>
                    <span style={{ fontSize:16, fontWeight:700 }}>{s.name||'Sin nombre'}</span>
                    <span style={{ fontSize:13, color:'var(--muted)', marginTop:2 }}>{s.email}</span>
                  </div>
                  <StatusBadge done={s.questionnaireCompleted} />
                  <Icon name="chevDown" size={20} color="var(--muted)"
                    style={{ transform: open?'rotate(180deg)':'none', transition:'.2s' }} />
                </button>
                {open && (
                  <div style={{ padding:'4px 20px 22px', borderTop:'1px solid var(--border)' }}>
                    {s.questionnaireCompleted && Object.keys(q).length > 0 ? (
                      <>
                        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:12, marginTop:16 }}>
                          {q.experience && <QAns label="Experiencia" value={q.experience} />}
                          {q.goal && <QAns label="Objetivo" value={q.goal} />}
                          {q.availableTime && <QAns label="Tiempo disponible" value={q.availableTime} />}
                          {q.guitar && <QAns label="Guitarra" value={q.guitar} />}
                        </div>
                        {q.style && (
                          <>
                            <div style={{ fontSize:12, color:'var(--gold)', fontWeight:700, margin:'18px 0 9px', letterSpacing:.3 }}>ESTILOS DE INTERÉS</div>
                            <div className="row" style={{ flexWrap:'wrap', gap:8 }}>
                              {(Array.isArray(q.style)?q.style:[q.style]).map(e=>(
                                <span key={e} style={{ fontSize:13, fontWeight:600, padding:'7px 13px', borderRadius:999, background:'var(--gold-soft)', border:'1px solid var(--gold-line)', color:'var(--gold)' }}>{e}</span>
                              ))}
                            </div>
                          </>
                        )}
                        {q.extra && (
                          <div style={{ marginTop:18, background:'var(--surface)', borderLeft:'3px solid var(--gold)', borderRadius:'0 10px 10px 0', padding:'13px 16px' }}>
                            <div style={{ fontSize:11.5, color:'var(--gold)', fontWeight:700, marginBottom:5 }}>NOTAS</div>
                            <div style={{ fontSize:14, color:'var(--text-2)', lineHeight:1.55 }}>{q.extra}</div>
                          </div>
                        )}
                        <div style={{ fontSize:12, color:'var(--muted)', marginTop:14 }}>
                          Registrado el {s.createdAt ? new Date(s.createdAt).toLocaleDateString('es-ES',{day:'numeric',month:'long',year:'numeric'}) : '—'}
                        </div>
                      </>
                    ) : (
                      <div style={{ fontSize:14, color:'var(--muted)', padding:'16px 0 2px' }}>
                        Este alumno todavía no ha completado el cuestionario inicial.
                      </div>
                    )}
                  </div>
                )}
              </div>
            );
          })
        }
      </div>
    </div>
  );
}

// ── Shell ────────────────────────────────────────────────────
const NAV = [
  { key:'dashboard', icon:'grid',      label:'Dashboard' },
  { key:'alumnos',   icon:'people',    label:'Alumnos'   },
  { key:'videos',    icon:'video',     label:'Vídeos'    },
];

function WebApp() {
  const [page, setPage] = React.useState('dashboard');

  const handleLogout = async () => {
    await window._fb.signOut(window._auth);
  };

  return (
    <div style={{ display:'flex', minHeight:'100vh' }}>
      <aside className="web-side">
        <div style={{ marginBottom:26 }}>
          <img src={LOGO} alt="GuitarFabrik" style={{ height:26, marginBottom:8 }} />
          <div className="brand-academy" style={{ fontSize:10, letterSpacing:5 }}>ACADEMY</div>
          <div style={{ fontSize:12, color:'var(--muted)', marginTop:6 }}>Panel del profesor</div>
        </div>
        <div className="col" style={{ gap:5 }}>
          {NAV.map(n => (
            <button key={n.key} className={`web-nav${page===n.key?' on':''}`} onClick={()=>setPage(n.key)}>
              <Icon name={n.icon} size={19} /> {n.label}
            </button>
          ))}
        </div>
        <div style={{ flex:1 }} />
        <button onClick={handleLogout} style={{ display:'flex', alignItems:'center', gap:10, border:'1px solid var(--border)', color:'var(--muted)', padding:'11px 14px', borderRadius:10, fontSize:14 }}
          onMouseOver={e=>e.currentTarget.style.borderColor='var(--muted)'}
          onMouseOut={e=>e.currentTarget.style.borderColor='var(--border)'}>
          <Icon name="logout" size={18} color="var(--muted)" /> Cerrar sesión
        </button>
      </aside>
      <main style={{ flex:1, minWidth:0, overflowY:'auto', padding:'34px 38px', background:'radial-gradient(1200px 600px at 70% 0%, #27241f 0%, transparent 55%), var(--bg)' }}>
        {page==='dashboard' && <WebDashboard />}
        {page==='alumnos'   && <WebAlumnos />}
        {page==='videos'    && <WebVideos />}
      </main>
    </div>
  );
}

// ── Root with auth guard ─────────────────────────────────────
function PanelRoot() {
  const [authState, setAuthState] = React.useState('loading'); // loading|out|in
  const [deniedMsg, setDeniedMsg] = React.useState('');

  React.useEffect(() => {
    return window._fb.onAuthStateChanged(window._auth, async (u) => {
      if (!u) { setAuthState('out'); return; }
      try {
        const snap = await window._fb.getDoc(window._fb.doc(window._db, 'users', u.uid));
        if (snap.exists() && snap.data().role === 'teacher') {
          setAuthState('in');
        } else {
          await window._fb.signOut(window._auth);
          setDeniedMsg('Esta cuenta no tiene acceso al panel.');
          setAuthState('out');
        }
      } catch {
        await window._fb.signOut(window._auth);
        setDeniedMsg('No se pudo verificar el acceso. Intenta de nuevo.');
        setAuthState('out');
      }
    });
  }, []);

  if (authState === 'loading') {
    return (
      <div style={{ minHeight:'100vh', display:'flex', alignItems:'center', justifyContent:'center', background:'var(--bg)' }}>
        <div style={{ width:40, height:40, borderRadius:'50%', border:'3px solid rgba(201,168,76,.18)', borderTopColor:'var(--gold)', animation:'spin .9s linear infinite' }} />
        <style>{`@keyframes spin{to{transform:rotate(360deg)}}`}</style>
      </div>
    );
  }

  if (authState === 'out') return <WebLogin onLogin={() => {}} deniedMsg={deniedMsg} />;
  return <WebApp />;
}

// Wait for Firebase to be ready before rendering
const mount = () => ReactDOM.createRoot(document.getElementById('root')).render(<PanelRoot />);
if (window._fbReady) { mount(); }
else { document.addEventListener('fbReady', mount, { once: true }); }
