// Componente Modular: Vista del Organizador (Mesa de Control, Locución y Radar Completo)
const { useState, useCallback } = React;

function OrganizerView({ onSwitchRole, currentUser }) {
  const room = window.useBingoRoom ? window.useBingoRoom() : {};
  
  // Verificación sólida de Organizador Autorizado (por prop, por sesión o por contexto)
  const effectiveUser = currentUser || (() => {
    try { return JSON.parse(localStorage.getItem('bingo_session_user')); } catch (e) { return null; }
  })();
  const isAuthorizedAdmin = 
    (effectiveUser?.role === 'admin' && (effectiveUser?.adminPin === '1234' || effectiveUser?.adminPin === 'LotaMami2026!' || effectiveUser?.originalRole === 'admin')) || 
    room.userRole === 'admin';

  // Protección de Acceso: Si el usuario no es Organizador/Admin, redirigir a la vista de espectador
  if (!isAuthorizedAdmin) {
    return <window.SpectatorView onSwitchRole={onSwitchRole} currentUser={currentUser} />;
  }

  const calledBalls = room.calledBalls || [];
  const currentBall = room.currentBall || null;
  const isAutoDrawing = room.isAutoDrawing || false;
  const drawPausedByPrize = room.drawPausedByPrize || false;
  const countdown = room.countdown !== undefined ? room.countdown : 5;
  const showMatrix = room.showMatrix || false;
  const setShowMatrix = room.setShowMatrix || (() => {});
  
  const voiceEnabled = room.voiceEnabled !== undefined ? room.voiceEnabled : true;
  const setVoiceEnabled = room.setVoiceEnabled || (() => {});
  const availableVoices = room.availableVoices || [];
  const selectedVoiceURI = room.selectedVoiceURI || '';
  const setSelectedVoiceURI = room.setSelectedVoiceURI || (() => {});
  const speechRate = room.speechRate !== undefined ? room.speechRate : 0.95;
  const setSpeechRate = room.setSpeechRate || (() => {});
  const speechPitch = room.speechPitch !== undefined ? room.speechPitch : 1.05;
  const setSpeechPitch = room.setSpeechPitch || (() => {});
  const voiceStyle = room.voiceStyle || 'oficial';
  const setVoiceStyle = room.setVoiceStyle || (() => {});
  const testVoice = room.testVoice || (() => {});
  const speakPhrase = room.speakPhrase || (() => {});

  const prize1Winner = room.prize1Winner || null;
  const prizeBingoWinner = room.prizeBingoWinner || null;
  const prizeCardRaffleWinner = room.prizeCardRaffleWinner || null;
  const isRafflingCard = room.isRafflingCard || false;
  const raffleDisplayCode = room.raffleDisplayCode || 'CR-?????';
  const latestAnnouncement = room.latestAnnouncement || null;
  const setLatestAnnouncement = room.setLatestAnnouncement || (() => {});

  const realRoomCards = room.realRoomCards || [];
  const radarRanking = room.radarRanking || [];
  const viewersCount = room.viewersCount || 52;
  const videoUrl = room.videoUrl || '';
  const updateVideoUrl = room.updateVideoUrl || (() => {});

  const currentRound = room.currentRound || 3;
  const roundBingoPrize = room.roundBingoPrize || (currentRound === 1 ? 100000 : 50000);
  const roundLineaPrize = room.roundLineaPrize || 10000;
  const roundCartonPrize = room.roundCartonPrize || 10000;
  const setActiveRound = room.setActiveRound || (() => {});

  const drawNextBall = room.drawNextBall || (() => {});
  const callSpecificBall = room.callSpecificBall || (() => {});
  const toggleAutoDraw = room.toggleAutoDraw || (() => {});
  const resetGame = room.resetGame || (() => {});
  const handleResetGameWithConfirmation = useCallback(() => {
    const confirmReset = window.confirm("⚠️ ¿Estás seguro de que deseas iniciar una NUEVA PARTIDA?\n\nEsto limpiará el bolillero y reiniciará los premios de la ronda.");
    if (confirmReset && resetGame) {
      resetGame();
    }
  }, [resetGame]);
  const raffleCardNumber = room.raffleCardNumber || (() => {});
  const isSalesOpen = room.isSalesOpen !== undefined ? room.isSalesOpen : true;
  const toggleSalesStatus = room.toggleSalesStatus || (() => {});

  const [organizerCardTab, setOrganizerCardTab] = useState('leaders');
  const [inspectedCard, setInspectedCard] = useState(null);
  const [showValidatorModal, setShowValidatorModal] = useState(false);
  const [validatorInitialCard, setValidatorInitialCard] = useState(null);
  const [quickValidateQuery, setQuickValidateQuery] = useState('');
  const [showVoiceModal, setShowVoiceModal] = useState(false);
  const [showVideoModal, setShowVideoModal] = useState(() => {
    try {
      const urlParams = new URLSearchParams(window.location.search);
      return urlParams.get('modal') === 'video';
    } catch (e) {
      return false;
    }
  });
  const [inputVideoUrl, setInputVideoUrl] = useState(() => room.videoUrl || '');
  const [saveSuccessMsg, setSaveSuccessMsg] = useState('');

  const handleToggleMatrix = useCallback(() => {
    setShowMatrix(prev => !prev);
  }, [setShowMatrix]);

  const handleToggleVoice = useCallback(() => {
    setVoiceEnabled(prev => !prev);
  }, [setVoiceEnabled]);

  const handleOpenVoiceSettings = useCallback(() => {
    setShowVoiceModal(true);
  }, []);

  const handleInspectCard = useCallback((card) => {
    setValidatorInitialCard(card);
    setShowValidatorModal(true);
  }, []);

  // Proclamación oficial de Línea o Bingo desde el validador
  const handleDeclareWinner = useCallback(async ({ prizeType, card, announcement, amount }) => {
    setLatestAnnouncement(announcement);

    try {
      if (window.supabaseClient) {
        await window.supabaseClient
          .from('game_sessions')
          .update({
            latest_announcement: announcement,
            status: prizeType === 'bingo' ? 'paused' : 'playing'
          })
          .eq('id', 'main-room');
      }
    } catch (err) {
      console.error("Error al actualizar game_sessions con ganador:", err);
    }

    if (voiceEnabled && ('speechSynthesis' in window)) {
      try {
        const pName = card?.playerName || 'Jugador';
        const cCode = card?.id || card?.card_code || '';
        const phrase = prizeType === 'bingo'
          ? `¡¡ATENCIÓN SEÑORAS Y SEÑORES!! ¡¡BINGO CONFIRMADO!! ¡¡EL CARTÓN GANADOR ES EL ${cCode} DE ${pName} CON LOS QUINCE NÚMEROS COMPLETOS!! ¡¡MUCHAS FELICITACIONES!!`
          : `¡¡ATENCIÓN SEÑORAS Y SEÑORES!! ¡¡LÍNEA CONFIRMADA!! ¡¡EL CARTÓN GANADOR DE LA LÍNEA ES EL ${cCode} DE ${pName}!! ¡¡CONTINUAMOS POR EL BINGO!!`;
        const utt = new SpeechSynthesisUtterance(phrase);
        utt.lang = 'es-ES';
        utt.pitch = 1.15;
        utt.rate = 1.05;
        window.speechSynthesis.speak(utt);
      } catch (e) {}
    }
  }, [voiceEnabled, setLatestAnnouncement]);

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '24px' }}>
      {/* ========================================================
          0. CONTROL Y ESTADO DE VENTAS DEL BINGO (ABRIR / CERRAR)
         ======================================================== */}
      <div style={{
        background: isSalesOpen 
          ? 'linear-gradient(135deg, rgba(16, 185, 129, 0.12), rgba(15, 23, 42, 0.9))'
          : 'linear-gradient(135deg, rgba(239, 68, 68, 0.16), rgba(15, 23, 42, 0.95))',
        border: isSalesOpen 
          ? '1.5px solid rgba(16, 185, 129, 0.5)' 
          : '1.5px solid rgba(239, 68, 68, 0.6)',
        borderRadius: 'var(--radius-lg)',
        padding: '16px 22px',
        display: 'flex',
        justifyContent: 'space-between',
        alignItems: 'center',
        flexWrap: 'wrap',
        gap: '16px',
        boxShadow: isSalesOpen 
          ? '0 4px 20px rgba(16, 185, 129, 0.15)' 
          : '0 4px 20px rgba(239, 68, 68, 0.22)'
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: '14px' }}>
          <div style={{
            width: '46px',
            height: '46px',
            borderRadius: '50%',
            background: isSalesOpen ? 'rgba(16, 185, 129, 0.2)' : 'rgba(239, 68, 68, 0.2)',
            border: isSalesOpen ? '2px solid #10b981' : '2px solid #ef4444',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            fontSize: '1.25rem',
            color: isSalesOpen ? '#10b981' : '#ef4444'
          }}>
            <i className={`fa-solid ${isSalesOpen ? 'fa-cart-shopping' : 'fa-lock'}`}></i>
          </div>
          <div>
            <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
              <span style={{
                fontSize: '0.75rem',
                fontWeight: '900',
                letterSpacing: '0.08em',
                textTransform: 'uppercase',
                padding: '3px 10px',
                borderRadius: 'var(--radius-full)',
                background: isSalesOpen ? 'rgba(16, 185, 129, 0.25)' : 'rgba(239, 68, 68, 0.25)',
                color: isSalesOpen ? '#34d399' : '#f87171',
                border: isSalesOpen ? '1px solid #10b981' : '1px solid #ef4444',
                display: 'inline-flex',
                alignItems: 'center',
                gap: '6px'
              }}>
                <span style={{
                  width: '7px',
                  height: '7px',
                  borderRadius: '50%',
                  backgroundColor: isSalesOpen ? '#10b981' : '#ef4444',
                  boxShadow: isSalesOpen ? '0 0 8px #10b981' : '0 0 8px #ef4444'
                }}></span>
                {isSalesOpen ? 'VENTA DE CARTONES: ABIERTA' : 'VENTA DE CARTONES: CERRADA'}
              </span>
            </div>
            <div style={{ fontSize: '0.88rem', color: '#ffffff', fontWeight: '700', marginTop: '4px' }}>
              {isSalesOpen
                ? 'Los jugadores pueden comprar cartones online y los vendedores pueden registrar ventas.'
                : 'La venta de cartones está bloqueada para jugadores y vendedores. El sorteo está en curso o por iniciar.'}
            </div>
          </div>
        </div>

        <div style={{ display: 'flex', gap: '10px', alignItems: 'center', flexWrap: 'wrap' }}>
          {/* Botón Destacado para Cargar Link de Transmisión de Video */}
          <button
            type="button"
            onClick={() => {
              setInputVideoUrl(videoUrl);
              setShowVideoModal(true);
              setSaveSuccessMsg('');
            }}
            className="btn btn-secondary"
            style={{
              padding: '10px 18px',
              fontSize: '0.9rem',
              fontWeight: '800',
              display: 'inline-flex',
              alignItems: 'center',
              gap: '8px',
              borderColor: videoUrl ? 'var(--accent-gold)' : 'rgba(56, 189, 248, 0.45)',
              background: videoUrl ? 'rgba(245, 158, 11, 0.15)' : 'rgba(56, 189, 248, 0.12)',
              color: videoUrl ? 'var(--accent-gold)' : '#38bdf8',
              boxShadow: videoUrl ? '0 0 12px rgba(245, 158, 11, 0.25)' : 'none'
            }}
            title="Configurar enlace de transmisión en vivo (YouTube, Facebook, Twitch, etc.)"
          >
            <i className={`fa-solid ${videoUrl ? 'fa-video' : 'fa-link'}`} style={{ fontSize: '1rem' }}></i>
            <span>{videoUrl ? 'Transmisión de Video Activa' : 'Cargar Link de Video'}</span>
          </button>

          {/* Botón Abrir / Cerrar Ventas */}
          {isSalesOpen ? (
            <button
              type="button"
              onClick={() => toggleSalesStatus(false)}
              className="btn"
              style={{
                padding: '10px 20px',
                fontSize: '0.92rem',
                fontWeight: '800',
                background: 'linear-gradient(135deg, #ef4444, #b91c1c)',
                color: '#ffffff',
                border: 'none',
                borderRadius: 'var(--radius-md)',
                boxShadow: '0 4px 14px rgba(239, 68, 68, 0.35)',
                cursor: 'pointer',
                display: 'inline-flex',
                alignItems: 'center',
                gap: '8px'
              }}
            >
              <i className="fa-solid fa-lock"></i>
              <span>Cerrar Venta de Cartones</span>
            </button>
          ) : (
            <button
              type="button"
              onClick={() => toggleSalesStatus(true)}
              className="btn"
              style={{
                padding: '10px 20px',
                fontSize: '0.92rem',
                fontWeight: '800',
                background: 'linear-gradient(135deg, #10b981, #059669)',
                color: '#ffffff',
                border: 'none',
                borderRadius: 'var(--radius-md)',
                boxShadow: '0 4px 14px rgba(16, 185, 129, 0.35)',
                cursor: 'pointer',
                display: 'inline-flex',
                alignItems: 'center',
                gap: '8px'
              }}
            >
              <i className="fa-solid fa-lock-open"></i>
              <span>Abrir / Habilitar Venta</span>
            </button>
          )}
        </div>
      </div>

      {/* ========================================================
          1. PODIO OFICIAL DE PREMIOS ($240.000 EN 3 RONDAS + GRAN SORTEO FINAL)
         ======================================================== */}
      <window.Premios 
        prize1Winner={prize1Winner}
        prizeBingoWinner={prizeBingoWinner}
        prizeCardRaffleWinner={prizeCardRaffleWinner}
        isRafflingCard={isRafflingCard}
        raffleDisplayCode={raffleDisplayCode}
        currentRound={currentRound}
        roundBingoPrize={roundBingoPrize}
        roundLineaPrize={roundLineaPrize}
        roundCartonPrize={roundCartonPrize}
        onSelectRound={setActiveRound}
      />

      {/* BANNER OFICIAL DE PREMIO CANTADO / COMPARTIDO (1 O N GANADORES) */}
      {latestAnnouncement && (
        <div style={{
          background: 'linear-gradient(135deg, rgba(245, 158, 11, 0.15), rgba(16, 185, 129, 0.15))',
          border: '1px solid rgba(245, 158, 11, 0.5)',
          borderRadius: 'var(--radius-lg)',
          padding: '14px 20px',
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          animation: 'popIn 0.3s ease',
          gap: '16px',
          boxShadow: '0 8px 24px rgba(245, 158, 11, 0.12)'
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: '14px' }}>
            <div style={{
              width: '46px',
              height: '46px',
              borderRadius: '50%',
              backgroundColor: 'rgba(245, 158, 11, 0.25)',
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
              fontSize: '1.3rem',
              color: 'var(--accent-gold)'
            }}>
              <i className="fa-solid fa-trophy"></i>
            </div>
            <div>
              <div style={{ fontSize: '1rem', fontWeight: '900', color: 'var(--accent-gold)' }}>
                {latestAnnouncement.title}
              </div>
              <div style={{ fontSize: '0.88rem', color: 'var(--text-main)', marginTop: '2px', fontWeight: '600' }}>
                {latestAnnouncement.message}
              </div>
            </div>
          </div>
          <div style={{ textAlign: 'right' }}>
            <div style={{ fontSize: '1.2rem', fontWeight: '900', color: 'var(--accent-green)' }}>
              {latestAnnouncement.amount}
            </div>
            <div style={{ fontSize: '0.75rem', color: 'var(--text-muted)' }}>
              {drawPausedByPrize ? '⏸️ Sorteo Pausado' : 'Premio Oficial'}
            </div>
          </div>
        </div>
      )}

      {/* ========================================================
          BARRA RÁPIDA DE VALIDACIÓN OFICIAL PARA EL LOCUTOR
         ======================================================== */}
      <div style={{
        background: 'linear-gradient(135deg, rgba(30, 41, 59, 0.95), rgba(15, 23, 42, 0.98))',
        border: '1.5px solid rgba(245, 158, 11, 0.45)',
        borderRadius: 'var(--radius-lg)',
        padding: '12px 18px',
        display: 'flex',
        justifyContent: 'space-between',
        alignItems: 'center',
        flexWrap: 'wrap',
        gap: '12px',
        boxShadow: '0 4px 20px rgba(0, 0, 0, 0.25)'
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
          <div style={{ width: '36px', height: '36px', borderRadius: '50%', backgroundColor: 'rgba(245, 158, 11, 0.2)', color: 'var(--accent-gold)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '1.1rem', fontWeight: '900' }}>
            <i className="fa-solid fa-certificate"></i>
          </div>
          <div>
            <span style={{ fontSize: '0.94rem', fontWeight: '900', color: '#ffffff', display: 'block' }}>
              Validador Rápido de Cartones (Línea / Bingo)
            </span>
            <span style={{ fontSize: '0.76rem', color: 'var(--text-muted)' }}>
              Verificación en 1 segundo con auditoría de filas y proclamación oficial en vivo
            </span>
          </div>
        </div>

        <div style={{ display: 'flex', gap: '8px', alignItems: 'center', flex: '1 1 320px', maxWidth: '480px' }}>
          <div style={{ position: 'relative', flex: 1 }}>
            <input
              type="text"
              className="input-field"
              placeholder="N° Cartón (ej: 70196) o Teléfono..."
              value={quickValidateQuery}
              onChange={(e) => setQuickValidateQuery(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === 'Enter') {
                  e.preventDefault();
                  if (quickValidateQuery.trim()) {
                    const found = realRoomCards.find(c => String(c.id || c.card_code).includes(quickValidateQuery.trim()));
                    setValidatorInitialCard(found || { id: quickValidateQuery.trim(), card_code: quickValidateQuery.trim() });
                    setShowValidatorModal(true);
                  } else {
                    setValidatorInitialCard(null);
                    setShowValidatorModal(true);
                  }
                }
              }}
              style={{ width: '100%', padding: '8px 12px', fontSize: '0.88rem' }}
            />
          </div>
          <button
            type="button"
            className="btn btn-primary btn-sm"
            onClick={() => {
              if (quickValidateQuery.trim()) {
                const found = realRoomCards.find(c => String(c.id || c.card_code).includes(quickValidateQuery.trim()));
                setValidatorInitialCard(found || { id: quickValidateQuery.trim(), card_code: quickValidateQuery.trim() });
                setShowValidatorModal(true);
              } else {
                setValidatorInitialCard(null);
                setShowValidatorModal(true);
              }
            }}
            style={{
              padding: '8px 14px',
              fontWeight: '800',
              fontSize: '0.82rem',
              background: 'linear-gradient(135deg, var(--accent-gold), #d97706)',
              color: '#111827',
              borderColor: 'var(--accent-gold)',
              whiteSpace: 'nowrap'
            }}
          >
            <i className="fa-solid fa-stamp"></i> Validar
          </button>
          <button
            type="button"
            className="btn btn-secondary btn-sm"
            onClick={() => {
              setValidatorInitialCard(null);
              setShowValidatorModal(true);
            }}
            style={{ padding: '8px 12px', fontSize: '0.82rem', whiteSpace: 'nowrap', color: 'var(--accent-teal)' }}
            title="Abrir panel completo del validador"
          >
            <i className="fa-solid fa-up-right-and-down-left-from-center"></i> Abrir
          </button>
        </div>
      </div>

      {/* ========================================================
          2. MESA DE CONTROL + RADAR DE LÍDERES
         ======================================================== */}
      <div className="grid-2-col">
        {/* Panel Izquierdo: Consola Bolillero & Voz */}
        <div className="organizer-control-deck">
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: '10px' }}>
            <div>
              <h3 style={{ fontSize: '1.2rem', fontWeight: '900', margin: 0, display: 'flex', alignItems: 'center', gap: '8px' }}>
                <i className="fa-solid fa-sliders" style={{ color: 'var(--accent-teal)' }}></i>
                Mesa de Control del Sorteo
              </h3>
              <span style={{ fontSize: '0.78rem', color: 'var(--text-muted)' }}>
                Motor Server-Side PostgreSQL | 👁️ {viewersCount} espectadores en vivo
              </span>
            </div>

            {/* Botones de Video, Voz, Validador y Locutor */}
            <div style={{ display: 'flex', gap: '8px', alignItems: 'center', flexWrap: 'wrap' }}>
              <button 
                className="btn btn-sm"
                onClick={() => {
                  setValidatorInitialCard(null);
                  setShowValidatorModal(true);
                }}
                style={{
                  display: 'flex',
                  alignItems: 'center',
                  gap: '6px',
                  background: 'linear-gradient(135deg, #f59e0b, #d97706)',
                  borderColor: '#f59e0b',
                  color: '#111827',
                  fontWeight: '900',
                  boxShadow: '0 2px 10px rgba(245, 158, 11, 0.35)'
                }}
                title="Validar cartón oficial al instante cuando canten Línea o Bingo"
              >
                <i className="fa-solid fa-stamp"></i>
                <span>🔍 Validar Cartón</span>
              </button>
              <button 
                className={`btn btn-sm ${videoUrl ? 'btn-primary' : 'btn-secondary'}`}
                onClick={() => {
                  setInputVideoUrl(videoUrl);
                  setShowVideoModal(true);
                  setSaveSuccessMsg('');
                }}
                title="Configurar enlace de video o transmisión en vivo del bolillero"
                style={{ display: 'flex', alignItems: 'center', gap: '6px', border: videoUrl ? '1px solid var(--accent-gold)' : undefined }}
              >
                <i className={`fa-solid ${videoUrl ? 'fa-video' : 'fa-link'}`} style={{ color: videoUrl ? 'var(--accent-gold)' : 'var(--accent-teal)' }}></i>
                <span>{videoUrl ? 'Video Activo' : 'Link Video'}</span>
              </button>

              <button 
                className="btn btn-secondary btn-sm"
                onClick={handleOpenVoiceSettings}
                title="Configurar voz, velocidad y estilo del locutor"
                style={{ display: 'flex', alignItems: 'center', gap: '6px' }}
              >
                <i className="fa-solid fa-microphone-lines" style={{ color: 'var(--accent-teal)' }}></i>
                <span>Voz / Locutor</span>
              </button>

              <button 
                className={`btn btn-sm ${voiceEnabled ? 'btn-primary' : 'btn-secondary'}`}
                onClick={handleToggleVoice}
                title="Activar o silenciar dictado de números"
              >
                <i className={`fa-solid ${voiceEnabled ? 'fa-volume-high' : 'fa-volume-xmark'}`}></i>
                {voiceEnabled ? 'Activo' : 'Mudo'}
              </button>
            </div>
          </div>

          {/* Componente Atómico Bolillero */}
          <window.Bolillero 
            currentBall={currentBall}
            calledBalls={calledBalls}
            viewersCount={viewersCount}
            isSpectator={false}
            size={130}
          />

          {/* Componente Atómico Controles del Organizador */}
          <window.ControlesOrganizador 
            calledBallsCount={calledBalls.length}
            calledBalls={calledBalls}
            isAutoDrawing={isAutoDrawing}
            drawPausedByPrize={drawPausedByPrize}
            countdown={countdown}
            voiceEnabled={voiceEnabled}
            isRafflingCard={isRafflingCard}
            prizeCardRaffleWinner={prizeCardRaffleWinner}
            prizeBingoWinner={prizeBingoWinner}
            showMatrix={showMatrix}
            currentRound={currentRound}
            roundBingoPrize={roundBingoPrize}
            onSetActiveRound={setActiveRound}
            onDrawNextBall={drawNextBall}
            onCallSpecificBall={callSpecificBall}
            onToggleAutoDraw={toggleAutoDraw}
            onResetGame={handleResetGameWithConfirmation}
            onRaffleCardNumber={raffleCardNumber}
            onToggleMatrix={handleToggleMatrix}
            onToggleVoice={handleToggleVoice}
            onOpenVoiceSettings={handleOpenVoiceSettings}
          />

          {/* Componente Atómico Tablero 1 a 90 */}
          <window.Tablero 
            calledBalls={calledBalls}
            isOpen={showMatrix}
            onToggle={handleToggleMatrix}
            onSelectBall={callSpecificBall}
            interactive={true}
          />
        </div>

        {/* Panel Derecho: Componente Atómico Radar de Líderes 3x9 */}
        <window.Radar 
          radarRanking={radarRanking}
          realRoomCards={realRoomCards}
          calledBalls={calledBalls}
          activeTab={organizerCardTab}
          onTabChange={setOrganizerCardTab}
          onInspectCard={handleInspectCard}
        />
      </div>

      {/* ========================================================
          3. MODAL OFICIAL: VALIDADOR RÁPIDO DE CARTONES (LÍNEA / BINGO)
         ======================================================== */}
      {showValidatorModal && window.CardValidatorModal && (
        <window.CardValidatorModal
          isModal={true}
          onClose={() => {
            setShowValidatorModal(false);
            setValidatorInitialCard(null);
          }}
          initialCard={validatorInitialCard}
          calledBalls={calledBalls}
          realRoomCards={realRoomCards}
          currentRound={currentRound}
          roundBingoPrize={roundBingoPrize}
          roundLineaPrize={roundLineaPrize}
          onDeclareWinner={handleDeclareWinner}
        />
      )}

      {/* ========================================================
          4. MODAL AJUSTES DE LOCUTOR (Web Speech API)
         ======================================================== */}
      {showVoiceModal && (
        <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0, 0, 0, 0.82)', backdropFilter: 'blur(6px)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 99999, padding: '20px' }}>
          <div className="app-card" style={{ maxWidth: '520px', width: '100%', animation: 'popIn 0.25s ease' }}>
            <div className="card-header" style={{ marginBottom: '16px' }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
                <i className="fa-solid fa-microphone-lines" style={{ color: 'var(--accent-teal)', fontSize: '1.2rem' }}></i>
                <h3 className="card-title" style={{ margin: 0 }}>Ajustes del Locutor Oficial</h3>
              </div>
              <button className="btn btn-secondary btn-sm" onClick={() => setShowVoiceModal(false)}>
                <i className="fa-solid fa-xmark"></i>
              </button>
            </div>

            <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
              <div>
                <label style={{ fontSize: '0.85rem', fontWeight: '700', color: 'var(--text-main)', marginBottom: '6px', display: 'block' }}>
                  Voz del Sintetizador:
                </label>
                <select 
                  className="input-field" 
                  value={selectedVoiceURI} 
                  onChange={(e) => setSelectedVoiceURI(e.target.value)}
                  style={{ width: '100%', padding: '10px' }}
                >
                  {availableVoices.map((v, i) => (
                    <option key={v.voiceURI || i} value={v.voiceURI}>
                      {v.name} ({v.lang})
                    </option>
                  ))}
                  {availableVoices.length === 0 && (
                    <option value="">Voz predeterminada del navegador (Español)</option>
                  )}
                </select>
              </div>

              <div>
                <label style={{ fontSize: '0.85rem', fontWeight: '700', color: 'var(--text-main)', marginBottom: '6px', display: 'block' }}>
                  Estilo de Dictado:
                </label>
                <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: '8px' }}>
                  <button 
                    className={`btn btn-sm ${voiceStyle === 'oficial' || voiceStyle === 'natural' ? 'btn-primary' : 'btn-secondary'}`}
                    onClick={() => setVoiceStyle('oficial')}
                  >
                    "¡El 52!" (Natural)
                  </button>
                  <button 
                    className={`btn btn-sm ${voiceStyle === 'clasico' ? 'btn-primary' : 'btn-secondary'}`}
                    onClick={() => setVoiceStyle('clasico')}
                  >
                    "Con Apodos"
                  </button>
                  <button 
                    className={`btn btn-sm ${voiceStyle === 'formal' ? 'btn-primary' : 'btn-secondary'}`}
                    onClick={() => setVoiceStyle('formal')}
                  >
                    "Bolilla 52"
                  </button>
                </div>
              </div>

              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '14px' }}>
                <div>
                  <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: '0.8rem', color: 'var(--text-muted)', marginBottom: '4px' }}>
                    <span>Velocidad (Rate):</span>
                    <strong>{speechRate}x</strong>
                  </div>
                  <input 
                    type="range" 
                    min="0.80" 
                    max="1.3" 
                    step="0.05" 
                    value={speechRate}
                    onChange={(e) => setSpeechRate(parseFloat(e.target.value))}
                    style={{ width: '100%' }}
                  />
                </div>

                <div>
                  <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: '0.8rem', color: 'var(--text-muted)', marginBottom: '4px' }}>
                    <span>Tono (Pitch):</span>
                    <strong>{speechPitch}</strong>
                  </div>
                  <input 
                    type="range" 
                    min="0.8" 
                    max="1.3" 
                    step="0.05" 
                    value={speechPitch}
                    onChange={(e) => setSpeechPitch(parseFloat(e.target.value))}
                    style={{ width: '100%' }}
                  />
                </div>
              </div>

              {/* Botones de Prueba Rápida de Frases Oficiales con Mención de Ganadores */}
              <div>
                <label style={{ fontSize: '0.82rem', fontWeight: '700', color: 'var(--text-main)', marginBottom: '6px', display: 'block' }}>
                  Probar Frases con Mención del Ganador por Voz:
                </label>
                <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8px' }}>
                  <button 
                    type="button"
                    className="btn btn-secondary btn-sm"
                    onClick={() => speakPhrase ? speakPhrase('bolilla_52') : testVoice("¡El cincuenta y dos!")}
                    title="Canto directo de bolilla"
                  >
                    <i className="fa-solid fa-volume-high"></i> "¡El 52!"
                  </button>
                  <button 
                    type="button"
                    className="btn btn-secondary btn-sm"
                    onClick={() => speakPhrase ? speakPhrase('linea_ganador') : testVoice("¡¡ATENCIÓN!! ¡¡Ganador de Primera Línea: Daniela G!!")}
                    title="Ganador de Primera Línea"
                    style={{ color: 'var(--accent-gold)' }}
                  >
                    <i className="fa-solid fa-trophy"></i> 🥇 Ganador 1ª Línea
                  </button>
                  <button 
                    type="button"
                    className="btn btn-secondary btn-sm"
                    onClick={() => speakPhrase ? speakPhrase('bingo_ganador') : testVoice(`¡¡¡BINGO, BINGO, BINGO del Premio ${currentRound}: Ganador del pozo mayor!!!`)}
                    title="Ganador del Gran Bingo"
                    style={{ color: 'var(--accent-green)', fontWeight: '800' }}
                  >
                    <i className="fa-solid fa-crown"></i> 👑 Ganador BINGO
                  </button>
                  <button 
                    type="button"
                    className="btn btn-secondary btn-sm"
                    onClick={() => speakPhrase ? speakPhrase('sorteo_serie') : testVoice("¡¡Ganador de Serie: Eduvijes!!")}
                    title="Ganador del Sorteo de Serie"
                    style={{ gridColumn: 'span 2', color: 'var(--accent-cyan)' }}
                  >
                    <i className="fa-solid fa-ticket"></i> 🎟️ Ganador Sorteo de Serie ($10k)
                  </button>
                </div>
              </div>

              {/* Botón de Cierre */}
              <div style={{ display: 'flex', gap: '10px', marginTop: '6px' }}>
                <button 
                  className="btn btn-primary" 
                  style={{ width: '100%', padding: '10px', fontWeight: '800' }}
                  onClick={() => setShowVoiceModal(false)}
                >
                  <i className="fa-solid fa-check"></i> Guardar Ajustes del Locutor
                </button>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* ========================================================
          5. MODAL CONFIGURACIÓN DE VIDEO EN VIVO (Bolillero Real)
         ======================================================== */}
      {showVideoModal && (
        <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0, 0, 0, 0.85)', backdropFilter: 'blur(8px)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 99999, padding: '20px' }}>
          <div className="app-card" style={{ maxWidth: '580px', width: '100%', animation: 'popIn 0.25s ease', border: '1px solid rgba(245, 158, 11, 0.5)' }}>
            <div className="card-header" style={{ marginBottom: '16px' }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
                <div style={{ width: '38px', height: '38px', borderRadius: '50%', background: 'rgba(239, 68, 68, 0.2)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#f43f5e', fontSize: '1.2rem' }}>
                  <i className="fa-solid fa-video"></i>
                </div>
                <div>
                  <h3 className="card-title" style={{ margin: 0, fontSize: '1.15rem' }}>Transmisión de Video del Sorteo</h3>
                  <span style={{ fontSize: '0.78rem', color: 'var(--text-muted)' }}>Bolillero Físico en Directo o Video Grabado</span>
                </div>
              </div>
              <button className="btn btn-secondary btn-sm" onClick={() => setShowVideoModal(false)}>
                <i className="fa-solid fa-xmark"></i>
              </button>
            </div>

            <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
              <div style={{ background: 'rgba(245, 158, 11, 0.1)', border: '1px solid rgba(245, 158, 11, 0.3)', padding: '10px 14px', borderRadius: 'var(--radius-md)', fontSize: '0.84rem', color: '#fef08a', lineHeight: 1.5 }}>
                <i className="fa-solid fa-lightbulb" style={{ color: 'var(--accent-gold)', marginRight: '6px' }}></i>
                Pega el enlace de tu transmisión o video (<strong>YouTube Live, YouTube, Twitch, Facebook Live, Google Meet o video MP4</strong>). Todos los espectadores lo verán sincronizado en su pantalla.
              </div>

              <div>
                <label style={{ fontSize: '0.86rem', fontWeight: '800', color: 'var(--text-main)', marginBottom: '6px', display: 'block' }}>
                  Enlace del Video o Transmisión:
                </label>
                <input 
                  type="url"
                  className="form-input"
                  placeholder="Ej: https://www.youtube.com/watch?v=... o https://youtu.be/..."
                  value={inputVideoUrl}
                  onChange={(e) => {
                    setInputVideoUrl(e.target.value);
                    setSaveSuccessMsg('');
                  }}
                  style={{ width: '100%', padding: '10px 12px', fontSize: '0.92rem' }}
                  autoFocus
                />
              </div>

              {/* Vista Previa del Video si es YouTube */}
              {(() => {
                const trimmed = (inputVideoUrl || '').trim();
                const ytMatch = trimmed.match(/(?:youtube\.com\/(?:watch\?v=|live\/|embed\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/);
                if (ytMatch) {
                  return (
                    <div style={{ borderRadius: 'var(--radius-md)', overflow: 'hidden', border: '1px solid rgba(255, 255, 255, 0.15)', background: '#000' }}>
                      <div style={{ fontSize: '0.75rem', padding: '6px 12px', color: 'var(--accent-green)', background: 'rgba(16, 185, 129, 0.15)', display: 'flex', alignItems: 'center', gap: '6px' }}>
                        <i className="fa-solid fa-circle-check"></i> Vista previa detectada de YouTube
                      </div>
                      <div style={{ position: 'relative', paddingBottom: '45%', height: 0 }}>
                        <iframe
                          src={`https://www.youtube.com/embed/${ytMatch[1]}`}
                          style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', border: 0 }}
                          title="Vista Previa"
                        ></iframe>
                      </div>
                    </div>
                  );
                }
                return null;
              })()}

              {saveSuccessMsg && (
                <div style={{ background: 'rgba(16, 185, 129, 0.15)', border: '1px solid var(--accent-green)', padding: '10px', borderRadius: 'var(--radius-md)', color: 'var(--accent-green)', fontSize: '0.85rem', textAlign: 'center', fontWeight: '700' }}>
                  <i className="fa-solid fa-circle-check" style={{ marginRight: '6px' }}></i>
                  {saveSuccessMsg}
                </div>
              )}

              {/* Botones de Acción */}
              <div style={{ display: 'flex', flexDirection: 'column', gap: '8px', marginTop: '4px' }}>
                <button 
                  type="button"
                  className="btn btn-primary"
                  style={{ width: '100%', padding: '12px', fontWeight: '800', fontSize: '0.95rem' }}
                  onClick={() => {
                    updateVideoUrl(inputVideoUrl);
                    setSaveSuccessMsg('¡Enlace de video guardado y transmitido a todos los espectadores!');
                    setTimeout(() => setShowVideoModal(false), 900);
                  }}
                >
                  <i className="fa-solid fa-tower-broadcast"></i> Guardar y Transmitir a Espectadores
                </button>

                <div style={{ display: 'flex', gap: '8px' }}>
                  {inputVideoUrl && (
                    <a
                      href={inputVideoUrl}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="btn btn-secondary btn-sm"
                      style={{ flex: 1, padding: '8px', fontSize: '0.82rem', textAlign: 'center', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '6px', textDecoration: 'none' }}
                    >
                      <i className="fa-solid fa-arrow-up-right-from-square"></i> Probar en Nueva Pestaña
                    </a>
                  )}

                  {videoUrl && (
                    <button
                      type="button"
                      className="btn btn-secondary btn-sm"
                      style={{ flex: 1, padding: '8px', fontSize: '0.82rem', color: '#fca5a5' }}
                      onClick={() => {
                        updateVideoUrl('');
                        setInputVideoUrl('');
                        setSaveSuccessMsg('Transmisión de video desactivada.');
                        setTimeout(() => setShowVideoModal(false), 700);
                      }}
                    >
                      <i className="fa-solid fa-trash-can"></i> Quitar Video
                    </button>
                  )}
                </div>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

window.OrganizerView = OrganizerView;
