/* live-views.jsx — Guest / DJ / TV / Lobby views for the real app */
/* eslint-disable */

// ════════════════════════════════════════════════════════════
// LOBBY — landing page when no ?role= is set
// ════════════════════════════════════════════════════════════
function Lobby({ onPickRole }) {
  const [roomCode, setRoomCode] = React.useState(CFG.room);
  const [clientId, setClientId] = React.useState(CFG.clientId);
  const [showAdvanced, setShowAdvanced] = React.useState(false);

  const apply = () => {
    localStorage.setItem('sonarium.config.room', roomCode);
    if (clientId) localStorage.setItem('sonarium.config.clientId', clientId);
    else localStorage.removeItem('sonarium.config.clientId');
    location.reload();
  };

  return (
    <AuroraScreen>
      <div style={{
        minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center',
        padding: '40px 20px',
      }}>
        <div style={{ maxWidth: 720, width: '100%' }}>
          {/* Header */}
          <div style={{ display: 'flex', alignItems: 'center', gap: 14, marginBottom: 36 }}>
            <FSJAMark size={48}/>
            <div>
              <div style={{ fontSize: 11, letterSpacing: '0.22em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.55)', marginBottom: 4 }}>
                Fundación San Juan de Ávila
              </div>
              <div className="serif" style={{ fontSize: 30, lineHeight: 1 }}>
                Sonarium <span style={{ color: 'var(--gold-500)' }}>·</span> Sala <span className="mono" style={{ color: 'var(--gold-500)' }}>{roomCode}</span>
              </div>
            </div>
          </div>

          <div className="serif" style={{ fontSize: 50, lineHeight: 1.05, marginBottom: 12, letterSpacing: '-0.01em' }}>
            ¿Quién <em style={{ color: 'var(--gold-500)', fontStyle: 'italic' }}>eres</em> hoy?
          </div>
          <div style={{ fontSize: 15.5, color: 'rgba(255,255,255,0.6)', marginBottom: 32, maxWidth: 480, lineHeight: 1.5 }}>
            Elige cómo abres Sonarium. Los enlaces directos se ven en cada tarjeta — guárdalos.
          </div>

          {/* Role cards */}
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 14, marginBottom: 28 }}>
            <RoleCard
              icon={Icon.user(22)}
              title="Soy invitado"
              desc="Pedir y dedicar canciones."
              href={`?role=guest&room=${roomCode}`}
              onClick={() => onPickRole('guest')}
            />
            <RoleCard
              icon={Icon.music(22)}
              title="Soy DJ"
              desc="Aprobar peticiones y controlar la música."
              href={`?role=dj&room=${roomCode}`}
              onClick={() => onPickRole('dj')}
              accent
            />
            <RoleCard
              icon={Icon.bolt(22)}
              title="Pantalla / TV"
              desc="Vista pública en el proyector."
              href={`?role=tv&room=${roomCode}`}
              onClick={() => onPickRole('tv')}
            />
          </div>

          {/* Config */}
          <div className="glass" style={{ padding: 22 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 14 }}>
              <div style={{ fontSize: 12, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.6)', fontWeight: 600 }}>
                Configuración
              </div>
              <button onClick={() => setShowAdvanced(v => !v)} style={{
                background: 'none', border: 'none', color: 'var(--gold-500)', cursor: 'pointer',
                fontSize: 12, fontFamily: 'inherit', textDecoration: 'underline', textDecorationStyle: 'dotted',
              }}>{showAdvanced ? 'Ocultar' : 'Avanzado'}</button>
            </div>

            <div style={{ display: 'grid', gridTemplateColumns: '1fr', gap: 12 }}>
              <label>
                <div style={{ fontSize: 11.5, color: 'rgba(255,255,255,0.6)', marginBottom: 6, letterSpacing: '0.04em' }}>
                  Código de sala
                </div>
                <input className="glass-input" value={roomCode} onChange={(e) => setRoomCode(e.target.value.toUpperCase().replace(/[^A-Z0-9-]/g, ''))}/>
              </label>

              {showAdvanced && (
                <label>
                  <div style={{ fontSize: 11.5, color: 'rgba(255,255,255,0.6)', marginBottom: 6, letterSpacing: '0.04em' }}>
                    Spotify Client ID <span style={{ color: 'rgba(255,255,255,0.4)' }}>(opcional · solo para el DJ)</span>
                  </div>
                  <input className="glass-input" value={clientId} onChange={(e) => setClientId(e.target.value.trim())}
                    placeholder="0123abcd…  ·  vacío = modo demo"/>
                  <div style={{ fontSize: 11, color: 'rgba(255,255,255,0.45)', marginTop: 6, lineHeight: 1.5 }}>
                    Créalo en <span className="mono" style={{ color: 'var(--gold-300)' }}>developer.spotify.com/dashboard</span>.
                    Añade <span className="mono" style={{ color: 'var(--gold-300)' }}>{CFG.redirectUri}</span> como Redirect URI.
                  </div>
                </label>
              )}

              <button className="btn-gold" onClick={apply} style={{
                height: 44, borderRadius: 12, fontSize: 14, marginTop: 4,
              }}>Guardar configuración</button>
            </div>
          </div>

          <div style={{
            marginTop: 22, fontSize: 11.5, color: 'rgba(255,255,255,0.4)',
            textAlign: 'center', lineHeight: 1.6,
          }}>
            {CFG.clientId
              ? <>Spotify configurado · <span style={{ color: 'var(--gold-500)' }}>modo real</span></>
              : <>Sin Spotify Client ID · <span style={{ color: 'var(--gold-500)' }}>modo demo</span> con catálogo de muestra</>}
          </div>
        </div>
      </div>
    </AuroraScreen>
  );
}

function RoleCard({ icon, title, desc, href, onClick, accent }) {
  return (
    <a href={href} onClick={(e) => { /* let nav happen */ }} className="glass" style={{
      padding: 18, textDecoration: 'none', color: '#fff', display: 'block',
      border: accent ? '0.5px solid rgba(229,169,58,0.4)' : 'none',
      transition: 'transform 0.15s, box-shadow 0.15s',
    }}>
      <div style={{
        width: 44, height: 44, borderRadius: 12,
        background: accent ? 'var(--gold-500)' : 'rgba(255,255,255,0.08)',
        color: accent ? '#1a1208' : 'var(--gold-500)',
        display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 14,
      }}>{icon}</div>
      <div style={{ fontSize: 16, fontWeight: 600, marginBottom: 4 }}>{title}</div>
      <div style={{ fontSize: 12.5, color: 'rgba(255,255,255,0.6)', lineHeight: 1.4 }}>{desc}</div>
    </a>
  );
}

// ════════════════════════════════════════════════════════════
// GUEST VIEW — mobile flow (welcome → search → form → success → live)
// ════════════════════════════════════════════════════════════
function GuestView() {
  const [room, roomApi] = useRoom(CFG.room);
  const toast = useToast();
  const [screen, setScreen] = React.useState('welcome');
  const [track, setTrack] = React.useState(null);
  const [submittedId, setSubmittedId] = React.useState(null);

  // Use DJ's shared token for real Spotify search; fall back to mock
  // Must be before early return to respect Rules of Hooks
  const searchClient = React.useMemo(() => {
    const tok = room?.djToken;
    if (tok && tok.access_token && tok.expires_at && Date.now() < tok.expires_at - 30_000) {
      return SpotifyClient.createSearchOnly(tok.access_token);
    }
    return SpotifyClient.createSearchOnly(null);
  }, [room?.djToken]);

  if (!room) return null;

  const submit = (req) => {
    const next = roomApi.submitRequest(req);
    const id = next.requests[next.requests.length - 1].id;
    setSubmittedId(id);
    setScreen('success');
    toast('¡Petición enviada!');
  };

  return (
    <AuroraScreen>
      <div style={{
        minHeight: '100vh', maxWidth: 460, margin: '0 auto',
        padding: '20px 18px 32px', position: 'relative',
      }}>
        <GuestTopBar room={room} onBack={screen === 'welcome' ? null : () => setScreen('welcome')}/>
        {screen === 'welcome' && <GuestWelcome onStart={() => setScreen('search')} onPeek={() => setScreen('live')}/>}
        {screen === 'search'  && <GuestSearch spotify={searchClient} onPick={(t) => { setTrack(t); setScreen('form'); }} onSkip={() => { setTrack(null); setScreen('form'); }}/>}
        {screen === 'form'    && <GuestForm track={track} onSubmit={submit} onBack={() => setScreen('search')}/>}
        {screen === 'success' && <GuestSuccess room={room} submittedId={submittedId} onAgain={() => { setTrack(null); setScreen('search'); }} onPeek={() => setScreen('live')}/>}
        {screen === 'live'    && <GuestLive room={room} mySubmittedId={submittedId} onBack={() => setScreen('welcome')}/>}
      </div>
    </AuroraScreen>
  );
}

function GuestTopBar({ room, onBack }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      marginBottom: 24,
    }}>
      {onBack ? (
        <button onClick={onBack} className="glass-pill" style={{
          width: 40, height: 40, border: 'none', color: '#fff', cursor: 'pointer',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M15 18l-6-6 6-6"/></svg>
        </button>
      ) : <div style={{ width: 40 }}/>}
      <div className="glass-pill" style={{
        height: 32, padding: '0 14px', display: 'flex', alignItems: 'center', gap: 8,
        fontSize: 11, letterSpacing: '0.1em', textTransform: 'uppercase',
        color: 'rgba(255,255,255,0.85)',
      }}>
        <FSJAMark size={16}/>
        Sala <span className="mono" style={{ color: 'var(--gold-500)' }}>{room.code}</span>
      </div>
      <div style={{ width: 40 }}/>
    </div>
  );
}

function GuestWelcome({ onStart, onPeek }) {
  return (
    <div className="fade-in" style={{ padding: '20px 4px 0' }}>
      <div style={{
        margin: '8px auto 32px', position: 'relative',
        width: 240, height: 240,
      }}>
        <div className="vinyl-spin" style={{
          position: 'absolute', inset: 0, borderRadius: '50%',
          background: 'radial-gradient(circle at center, #0a1a2e 24%, #111 25%, #0a0a0a 60%, #1b1b1b 61%, #0a0a0a 100%)',
          boxShadow: '0 24px 60px rgba(0,0,0,0.5)',
        }}>
          {[35, 50, 65, 80, 95].map(r => (
            <div key={r} style={{
              position: 'absolute', top: '50%', left: '50%',
              width: r * 2, height: r * 2, marginLeft: -r, marginTop: -r,
              border: '0.5px solid rgba(255,255,255,0.06)', borderRadius: '50%',
            }}/>
          ))}
          <div style={{
            position: 'absolute', top: '50%', left: '50%', width: 90, height: 90,
            marginLeft: -45, marginTop: -45, borderRadius: '50%',
            background: 'linear-gradient(135deg, #8b2332, #5a1620)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            boxShadow: 'inset 0 1px 0 rgba(255,255,255,0.2)',
          }}>
            <FSJAMark size={50}/>
          </div>
        </div>
      </div>

      <div className="serif" style={{ fontSize: 42, lineHeight: 1.02, textAlign: 'center', marginBottom: 14 }}>
        Pon música al<br/><em style={{ color: 'var(--gold-500)', fontStyle: 'italic' }}>encuentro.</em>
      </div>
      <div style={{
        textAlign: 'center', fontSize: 15, lineHeight: 1.5,
        color: 'rgba(255,255,255,0.62)', maxWidth: 300, margin: '0 auto 36px',
      }}>
        Pide una canción, dedícasela a alguien y descúbrela sonar en la fiesta.
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        <button className="btn-gold" style={{
          height: 54, borderRadius: 16, fontSize: 16,
          display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10,
        }} onClick={onStart}>{Icon.music(18)} Pedir una canción</button>
        <button className="btn-ghost" style={{
          height: 48, borderRadius: 14, fontSize: 14.5,
          display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
        }} onClick={onPeek}>{Icon.bolt(15)} Ver lo que está sonando</button>
      </div>
    </div>
  );
}

function GuestSearch({ spotify, onPick, onSkip }) {
  return (
    <div className="fade-in">
      <div className="serif" style={{ fontSize: 32, lineHeight: 1.1, marginBottom: 6 }}>
        Busca tu canción
      </div>
      <div style={{ fontSize: 13.5, color: 'rgba(255,255,255,0.55)', marginBottom: 22 }}>
        Escribe título, artista o álbum.
      </div>
      <TrackSearch spotify={spotify} onPick={onPick}/>

      <div style={{ marginTop: 24 }}>
        <div style={{ fontSize: 11, color: 'rgba(255,255,255,0.5)', letterSpacing: '0.1em', textTransform: 'uppercase', marginBottom: 12 }}>
          Sugeridas
        </div>
        <SuggestedTracks spotify={spotify} onPick={onPick}/>
      </div>

      <button onClick={onSkip} className="btn-ghost" style={{
        marginTop: 26, width: '100%', height: 44, borderRadius: 12, fontSize: 13,
      }}>No la encuentro · escribir a mano</button>
    </div>
  );
}

function SuggestedTracks({ spotify, onPick }) {
  const [tracks, setTracks] = React.useState([]);
  React.useEffect(() => {
    spotify.search('españa fiesta').then(setTracks).catch(() => setTracks([]));
  }, [spotify.isMock]);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      {tracks.slice(0, 5).map(t => (
        <button key={t.id} onClick={() => onPick(t)} className="glass-soft" style={{
          padding: 10, display: 'flex', alignItems: 'center', gap: 12,
          border: 'none', cursor: 'pointer', color: '#fff', fontFamily: 'inherit',
          textAlign: 'left', width: '100%',
        }}>
          <TrackArt track={t} size={40} radius={7}/>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 13.5, fontWeight: 500, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{t.name}</div>
            <div style={{ fontSize: 12, color: 'rgba(255,255,255,0.55)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{t.artists}</div>
          </div>
        </button>
      ))}
    </div>
  );
}

function GuestForm({ track, onSubmit, onBack }) {
  const [manual, setManual] = React.useState(!track);
  const [name, setName]     = React.useState(track?.name || '');
  const [artist, setArtist] = React.useState(track?.artists || '');
  const [from, setFrom]     = React.useState('');
  const [to, setTo]         = React.useState('');
  const [note, setNote]     = React.useState('');
  const [anon, setAnon]     = React.useState(false);

  const canSubmit = (manual ? (name.trim() && artist.trim()) : true) && to.trim() && (anon || from.trim());

  const handle = () => {
    const trackData = track || { id: `manual_${Date.now()}`, name: name.trim(), artists: artist.trim(), image: null, durationMs: 0, uri: '' };
    onSubmit({
      track: trackData,
      from: anon ? 'Anónimo' : from.trim(),
      to: to.trim(),
      note: note.trim(),
      anonymous: anon,
    });
  };

  return (
    <div className="fade-in">
      <div className="serif" style={{ fontSize: 30, lineHeight: 1.1, marginBottom: 18 }}>
        Tu petición
      </div>

      {/* Track card or manual fields */}
      {track && !manual ? (
        <div className="glass" style={{ padding: 14, marginBottom: 14, display: 'flex', alignItems: 'center', gap: 12 }}>
          <TrackArt track={track} size={56} radius={10}/>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 15, fontWeight: 600, marginBottom: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{track.name}</div>
            <div style={{ fontSize: 12.5, color: 'rgba(255,255,255,0.6)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{track.artists}</div>
          </div>
          <button onClick={onBack} className="glass-pill" style={{
            height: 32, padding: '0 12px', fontSize: 11.5, color: '#fff',
            border: 'none', cursor: 'pointer', fontFamily: 'inherit',
          }}>Cambiar</button>
        </div>
      ) : (
        <div className="glass" style={{ padding: 14, marginBottom: 14, display: 'flex', flexDirection: 'column', gap: 10 }}>
          <input className="glass-input" placeholder="Título de la canción" value={name} onChange={e => setName(e.target.value)}/>
          <input className="glass-input" placeholder="Artista o grupo"    value={artist} onChange={e => setArtist(e.target.value)}/>
        </div>
      )}

      {/* Dedication */}
      <div className="glass" style={{ padding: 16, marginBottom: 14 }}>
        <div style={{
          display: 'flex', alignItems: 'center', gap: 8, marginBottom: 14,
          color: 'var(--gold-500)', fontSize: 12, letterSpacing: '0.06em',
          textTransform: 'uppercase', fontWeight: 600,
        }}>
          {Icon.heart(14)} Dedicatoria
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
            <input className="glass-input" placeholder={anon ? 'Anónimo' : 'Tu nombre'} disabled={anon}
              value={anon ? '' : from} onChange={e => setFrom(e.target.value)}
              style={{ opacity: anon ? 0.5 : 1, padding: '12px 14px', fontSize: 14 }}/>
            <input className="glass-input" placeholder="Para quién" value={to} onChange={e => setTo(e.target.value)}
              style={{ padding: '12px 14px', fontSize: 14 }}/>
          </div>
          <textarea className="glass-input" rows={3} placeholder="Mensaje · opcional"
            value={note} onChange={e => setNote(e.target.value)}
            style={{ resize: 'none', minHeight: 72 }}/>
          <label style={{ display: 'flex', alignItems: 'center', gap: 10, fontSize: 13.5, color: 'rgba(255,255,255,0.75)', cursor: 'pointer', marginTop: 2 }}>
            <div onClick={() => setAnon(v => !v)} style={{
              width: 36, height: 22, borderRadius: 999, padding: 2,
              background: anon ? 'var(--gold-500)' : 'rgba(255,255,255,0.15)',
              transition: 'background 0.2s', flexShrink: 0,
            }}>
              <div style={{
                width: 18, height: 18, borderRadius: '50%', background: '#fff',
                transform: anon ? 'translateX(14px)' : 'translateX(0)',
                transition: 'transform 0.2s', boxShadow: '0 1px 3px rgba(0,0,0,0.3)',
              }}/>
            </div>
            Enviar de forma anónima
          </label>
        </div>
      </div>

      <button disabled={!canSubmit} onClick={handle} className="btn-gold" style={{
        width: '100%', height: 54, borderRadius: 16, fontSize: 16,
        display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10,
        opacity: canSubmit ? 1 : 0.4, cursor: canSubmit ? 'pointer' : 'not-allowed',
      }}>{Icon.send(17)} Enviar petición</button>

      <div style={{
        marginTop: 14, textAlign: 'center', fontSize: 11.5,
        color: 'rgba(255,255,255,0.4)', fontFamily: 'var(--font-mono)',
      }}>
        Pasa por moderación antes de sonar.
      </div>
    </div>
  );
}

function GuestSuccess({ room, submittedId, onAgain, onPeek }) {
  const req = room.requests.find(r => r.id === submittedId);
  // Estimate position: count pending+queued+next ahead
  const queueAhead = room.requests.filter(r =>
    (r.status === 'queued' || r.status === 'next') && r.id !== submittedId
  ).length;

  return (
    <div className="fade-in" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
      <div style={{
        width: 100, height: 100, borderRadius: '50%', marginTop: 16, marginBottom: 24,
        background: 'radial-gradient(circle at 30% 30%, #f3d27e, #b88727 70%)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        boxShadow: '0 12px 40px rgba(229,169,58,0.4), inset 0 1px 0 rgba(255,255,255,0.5)',
        color: '#1a1208',
      }}>
        <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><path d="M20 6L9 17l-5-5"/></svg>
      </div>

      <div className="serif" style={{ fontSize: 30, lineHeight: 1.1, textAlign: 'center', marginBottom: 6 }}>
        ¡Hecho{req && !req.anonymous ? `, ${req.from.split(' ')[0]}` : ''}!
      </div>
      <div style={{ textAlign: 'center', fontSize: 14.5, color: 'rgba(255,255,255,0.65)', maxWidth: 300, lineHeight: 1.5, marginBottom: 24 }}>
        Tu dedicatoria está en cola.<br/>Mira la pantalla cuando suene.
      </div>

      {req && (
        <div className="glass" style={{ width: '100%', padding: 18, marginBottom: 18 }}>
          <div style={{ display: 'flex', gap: 14, alignItems: 'center' }}>
            <TrackArt track={req.track} size={64} radius={12}/>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 11, color: 'rgba(255,255,255,0.5)', textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 4 }}>Tu petición</div>
              <div style={{ fontSize: 16, fontWeight: 600, lineHeight: 1.2, marginBottom: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{req.track.name}</div>
              <div style={{ fontSize: 13, color: 'rgba(255,255,255,0.6)' }}>{req.track.artists}</div>
            </div>
          </div>
          {(req.to || req.note) && (
            <>
              <div style={{ height: 1, background: 'rgba(255,255,255,0.1)', margin: '14px 0' }}/>
              <div style={{ fontSize: 13, color: 'rgba(255,255,255,0.7)', lineHeight: 1.5 }}>
                <span style={{ color: 'var(--gold-500)' }}>Para</span> {req.to}
                {req.note && (<><br/><span style={{ color: 'rgba(255,255,255,0.45)', fontStyle: 'italic' }}>«{req.note}»</span></>)}
              </div>
            </>
          )}
        </div>
      )}

      <div className="glass-soft" style={{
        width: '100%', padding: '14px 18px', marginBottom: 20,
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          {Icon.clock(16)}
          <div>
            <div style={{ fontSize: 12, color: 'rgba(255,255,255,0.55)' }}>Tu posición aprox.</div>
            <div style={{ fontSize: 15, fontWeight: 600 }}>~ #{queueAhead + 1} en la cola</div>
          </div>
        </div>
        <div className="tnum mono" style={{ fontSize: 22, color: 'var(--gold-500)', fontWeight: 600 }}>
          {Math.max(2, (queueAhead + 1) * 3)} min
        </div>
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 10, width: '100%' }}>
        <button onClick={onPeek} className="btn-gold" style={{
          height: 50, borderRadius: 14, fontSize: 15,
          display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
        }}>{Icon.bolt(15)} Ver la cola en directo</button>
        <button onClick={onAgain} className="btn-ghost" style={{ height: 46, borderRadius: 14, fontSize: 14 }}>
          Pedir otra
        </button>
      </div>
    </div>
  );
}

function GuestLive({ room, mySubmittedId, onBack }) {
  const playing = room.requests.find(r => r.status === 'playing');
  const next = room.requests.filter(r => r.status === 'next' || r.status === 'queued').slice(0, 6);

  return (
    <div className="fade-in">
      <div className="serif" style={{ fontSize: 30, lineHeight: 1.1, marginBottom: 18 }}>
        En directo
      </div>

      {playing && (
        <div className="glass" style={{ padding: 20, marginBottom: 18 }}>
          <div style={{
            fontSize: 11, color: 'var(--gold-500)', letterSpacing: '0.12em',
            textTransform: 'uppercase', marginBottom: 14, display: 'flex',
            alignItems: 'center', gap: 8,
          }}>
            <span className="eq-bar"/><span className="eq-bar"/><span className="eq-bar"/><span className="eq-bar"/><span className="eq-bar"/>
            <span style={{ marginLeft: 6 }}>Sonando ahora</span>
          </div>
          <div style={{ display: 'flex', gap: 14, alignItems: 'center' }}>
            <TrackArt track={playing.track} size={80} radius={14}/>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div className="serif" style={{ fontSize: 22, lineHeight: 1.1, marginBottom: 4 }}>{playing.track.name}</div>
              <div style={{ fontSize: 13.5, color: 'rgba(255,255,255,0.65)' }}>{playing.track.artists}</div>
            </div>
          </div>
          {(playing.to || playing.note) && (
            <div style={{
              marginTop: 14, padding: 12, borderRadius: 12,
              background: 'rgba(139,35,50,0.22)', border: '0.5px solid rgba(255,255,255,0.08)',
            }}>
              <div style={{ fontSize: 12, color: 'rgba(255,255,255,0.5)', marginBottom: 4 }}>
                de <strong style={{ color: '#fff', fontWeight: 600 }}>{playing.from}</strong> para <strong style={{ color: 'var(--gold-300)', fontWeight: 600 }}>{playing.to}</strong>
              </div>
              {playing.note && (
                <div style={{ fontSize: 13, lineHeight: 1.5, fontStyle: 'italic', color: 'rgba(255,255,255,0.85)' }}>«{playing.note}»</div>
              )}
            </div>
          )}
        </div>
      )}

      <div style={{ fontSize: 11, color: 'rgba(255,255,255,0.5)', letterSpacing: '0.12em', textTransform: 'uppercase', margin: '8px 4px 12px' }}>
        A continuación
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {next.length === 0 && (
          <div style={{ padding: 24, textAlign: 'center', color: 'rgba(255,255,255,0.45)', fontSize: 13.5 }}>
            Nadie ha pedido nada todavía. <span style={{ color: 'var(--gold-500)' }}>¡Sé el primero!</span>
          </div>
        )}
        {next.map((r, i) => {
          const mine = r.id === mySubmittedId;
          return (
            <div key={r.id} className="glass-soft" style={{
              padding: 10, display: 'flex', alignItems: 'center', gap: 12,
              border: mine ? '0.5px solid var(--gold-500)' : 'none',
            }}>
              <div className="tnum mono" style={{ width: 22, fontSize: 13, color: 'rgba(255,255,255,0.45)', textAlign: 'center' }}>{i + 1}</div>
              <TrackArt track={r.track} size={42} radius={9}/>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 14, fontWeight: 500, lineHeight: 1.2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{r.track.name}</div>
                <div style={{ fontSize: 11.5, color: 'rgba(255,255,255,0.5)', marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                  <span style={{ color: mine ? 'var(--gold-500)' : 'inherit' }}>{r.from}</span>
                  {r.to && <> → {r.to}</>}
                </div>
              </div>
              {mine && (
                <div className="glass-pill" style={{
                  height: 22, padding: '0 8px', fontSize: 10, fontWeight: 600,
                  letterSpacing: '0.06em', textTransform: 'uppercase', color: 'var(--gold-500)',
                  display: 'flex', alignItems: 'center',
                }}>Tuya</div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ════════════════════════════════════════════════════════════
// DJ WELCOME — pantalla de bienvenida / creación de sala
// ════════════════════════════════════════════════════════════
function DjWelcome() {
  const savedRoom = localStorage.getItem('sonarium.config.room');
  const savedName = localStorage.getItem('sonarium.config.djName');
  const hasSession = !!(savedRoom && savedName);

  const [isFirstVisit, setIsFirstVisit] = React.useState(!hasSession);
  const [djName,       setDjName]       = React.useState(savedName || '');
  const [roomCode,     setRoomCode]     = React.useState(savedRoom || generateRoomCode());

  const sanitize = (v) =>
    v.toUpperCase().replace(/[^A-Z0-9]/g, '-').replace(/-{2,}/g, '-').replace(/^-|-$/g, '').slice(0, 24);

  const enter = () => {
    const code = roomCode.trim();
    const name = djName.trim();
    if (!code || !name) return;
    localStorage.setItem('sonarium.config.djName', name);
    localStorage.setItem('sonarium.config.room',   code);
    window.location.href = `?role=dj&room=${encodeURIComponent(code)}`;
  };

  const startNew = () => {
    localStorage.removeItem('sonarium.config.room');
    localStorage.removeItem('sonarium.config.djName');
    setRoomCode(generateRoomCode());
    setDjName('');
    setIsFirstVisit(true);
  };

  return (
    <AuroraScreen>
      <div style={{
        minHeight: '100vh', display: 'flex', alignItems: 'center',
        justifyContent: 'center', padding: '40px 20px',
      }}>
        <div style={{ maxWidth: 360, width: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 20 }}>

          {/* Logo + título */}
          <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 4 }}>
            <FSJAMark size={40}/>
            <div className="serif" style={{ fontSize: 28, lineHeight: 1 }}>Sonarium</div>
          </div>

          {isFirstVisit ? (
            /* ── PRIMERA VISITA ── */
            <>
              <div style={{ fontSize: 14, color: 'rgba(255,255,255,.55)', textAlign: 'center' }}>
                Configura tu sala antes de empezar
              </div>

              <div className="glass" style={{ padding: 22, width: '100%', display: 'flex', flexDirection: 'column', gap: 14 }}>

                {/* Nombre del DJ */}
                <label>
                  <div style={{ fontSize: 11.5, color: 'rgba(255,255,255,.55)', marginBottom: 6, letterSpacing: '.04em' }}>
                    Tu nombre o alias
                  </div>
                  <input
                    className="glass-input"
                    placeholder="Ej: DJ Nombre"
                    value={djName}
                    onChange={(e) => setDjName(e.target.value)}
                    autoFocus
                  />
                </label>

                {/* Nombre de sala */}
                <label>
                  <div style={{ fontSize: 11.5, color: 'rgba(255,255,255,.55)', marginBottom: 6, letterSpacing: '.04em' }}>
                    Nombre de tu sala <span style={{ color: 'rgba(255,255,255,.35)' }}>(puedes cambiarlo)</span>
                  </div>
                  <div style={{ position: 'relative' }}>
                    <input
                      className="glass-input"
                      value={roomCode}
                      onChange={(e) => setRoomCode(sanitize(e.target.value))}
                      style={{ fontFamily: 'var(--font-mono)', fontWeight: 700, fontSize: 17, letterSpacing: '.05em', paddingRight: 40 }}
                    />
                    <button
                      onClick={() => setRoomCode(generateRoomCode())}
                      title="Generar otro"
                      style={{
                        position: 'absolute', right: 10, top: '50%', transform: 'translateY(-50%)',
                        background: 'none', border: 'none', color: 'rgba(255,255,255,.45)',
                        cursor: 'pointer', fontSize: 16, padding: 4, lineHeight: 1,
                      }}
                    >↻</button>
                  </div>
                  <div style={{ fontSize: 10.5, color: 'rgba(255,255,255,.35)', marginTop: 5 }}>
                    Aparecerá en el QR y en la pantalla TV
                  </div>
                </label>

                {/* QR preview */}
                <div style={{ background: 'rgba(255,255,255,.05)', borderRadius: 12, padding: 14, display: 'flex', alignItems: 'center', gap: 14 }}>
                  <div style={{ background: '#fff', borderRadius: 6, padding: 6, flexShrink: 0 }}>
                    <RealQR url={roomCode ? `${location.origin + location.pathname}?role=guest&room=${roomCode}` : ''} size={64} dark="#0a1a2e"/>
                  </div>
                  <div style={{ fontSize: 10, color: 'rgba(255,255,255,.4)', wordBreak: 'break-all', lineHeight: 1.5 }}>
                    {location.origin + location.pathname}?role=guest&room={roomCode || '…'}
                  </div>
                </div>

              </div>

              <button
                className="btn-gold"
                onClick={enter}
                disabled={!djName.trim() || !roomCode.trim()}
                style={{
                  width: '100%', height: 52, borderRadius: 14, fontSize: 15,
                  display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10,
                  opacity: (!djName.trim() || !roomCode.trim()) ? 0.4 : 1,
                  cursor: (!djName.trim() || !roomCode.trim()) ? 'not-allowed' : 'pointer',
                }}
              >
                {Icon.music(17)} Crear sala y abrir consola
              </button>
            </>
          ) : (
            /* ── VISITA POSTERIOR ── */
            <>
              <div style={{ fontSize: 14, color: 'rgba(255,255,255,.55)', textAlign: 'center' }}>
                Bienvenido de nuevo, <strong style={{ color: '#fff' }}>{savedName}</strong>
              </div>

              {/* Continuar sala */}
              <div className="glass" style={{ padding: 22, width: '100%', textAlign: 'center' }}>
                <div style={{ fontSize: 11, color: 'var(--gold-500)', letterSpacing: '.14em', textTransform: 'uppercase', marginBottom: 10, fontWeight: 600 }}>
                  Tu sala
                </div>
                <div className="mono" style={{ fontSize: 26, fontWeight: 700, letterSpacing: '.05em', marginBottom: 16 }}>
                  {savedRoom}
                </div>
                <button className="btn-gold" onClick={enter} style={{
                  width: '100%', height: 48, borderRadius: 12, fontSize: 14,
                  display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
                }}>
                  {Icon.arrow(16)} Continuar sesión
                </button>
              </div>

              <div style={{ fontSize: 12, color: 'rgba(255,255,255,.35)' }}>— o —</div>

              {/* Nueva sala */}
              <div className="glass-soft" style={{ padding: 18, width: '100%', textAlign: 'center', borderRadius: 18 }}>
                <div style={{ fontSize: 14, fontWeight: 600, color: 'rgba(255,255,255,.8)', marginBottom: 6 }}>
                  Nueva sala
                </div>
                <div style={{ fontSize: 12, color: 'rgba(255,255,255,.45)', marginBottom: 14, lineHeight: 1.5 }}>
                  Se generará un código nuevo y el historial actual se borrará
                </div>
                <button className="btn-ghost" onClick={startNew} style={{
                  width: '100%', height: 42, borderRadius: 11, fontSize: 13,
                }}>
                  Crear nueva sala
                </button>
              </div>
            </>
          )}

        </div>
      </div>
    </AuroraScreen>
  );
}

Object.assign(window, { Lobby, GuestView, DjWelcome });
