// Componente Oficial: Validador Rápido de Cartones para el Locutor y Administrador
const { useState, useMemo, useEffect, useCallback } = React;

function CardValidator({
  calledBalls = [],
  realRoomCards = [],
  currentRound = 1,
  roundBingoPrize = 100000,
  roundLineaPrize = 10000,
  onDeclareWinner = null,
  initialCard = null,
  isModal = false,
  onClose = null
}) {
  const [searchQuery, setSearchQuery] = useState('');
  const [selectedCard, setSelectedCard] = useState(initialCard || null);
  const [searchResults, setSearchResults] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [notFoundMsg, setNotFoundMsg] = useState('');
  const [announcementSent, setAnnouncementSent] = useState(null);

  // Sincronizar si cambia initialCard desde afuera
  useEffect(() => {
    if (initialCard) {
      setSelectedCard(initialCard);
      setSearchQuery(initialCard.id || initialCard.card_code || '');
    }
  }, [initialCard]);

  // Conjunto de bolillas cantadas para chequeo O(1)
  const calledSet = useMemo(() => {
    return new Set(calledBalls.map(b => (typeof b === 'number' ? b : b.num)));
  }, [calledBalls]);

  // Función normalizadora de teléfono
  const normalizeDigits = (val) => String(val || '').replace(/[^0-9]/g, '');

  // Búsqueda inteligente de cartones
  const handleSearch = useCallback(async (queryText) => {
    const raw = (queryText !== undefined ? queryText : searchQuery).trim();
    if (!raw) return;

    setIsLoading(true);
    setNotFoundMsg('');
    setAnnouncementSent(null);

    const queryLower = raw.toLowerCase();
    const queryDigits = normalizeDigits(raw);
    let matched = [];

    // 1. Buscar primero en los cartones en memoria (realRoomCards)
    if (realRoomCards && realRoomCards.length > 0) {
      matched = realRoomCards.filter(c => {
        const cid = String(c.id || c.card_code || '').toLowerCase();
        const cPhone = normalizeDigits(c.playerPhone || c.player_phone);
        const cName = String(c.playerName || c.player_name || '').toLowerCase();

        if (cid === queryLower || cid.includes(queryLower)) return true;
        if (queryDigits && cPhone.includes(queryDigits)) return true;
        if (cName.includes(queryLower)) return true;
        return false;
      });
    }

    // 2. Si no se encontró en memoria, consultar directamente a Supabase
    if (matched.length === 0 && window.supabaseClient) {
      try {
        const { data: dbCards } = await window.supabaseClient
          .from('bingo_cards')
          .select('*')
          .or(`card_code.ilike.%${raw}%,player_name.ilike.%${raw}%,player_phone.ilike.%${queryDigits}%`)
          .limit(20);

        if (dbCards && dbCards.length > 0) {
          // Obtener información adicional de comprobantes/vendedores si están disponibles
          const receiptIds = [...new Set(dbCards.map(c => c.receipt_id).filter(Boolean))];
          let receiptsMap = {};
          if (receiptIds.length > 0) {
            const { data: recs } = await window.supabaseClient
              .from('receipts')
              .select('id, seller_name, payment_method, status, amount')
              .in('id', receiptIds);
            if (recs) {
              recs.forEach(r => { receiptsMap[r.id] = r; });
            }
          }

          matched = dbCards.map((c, idx) => ({
            id: c.card_code || c.id,
            card_code: c.card_code || c.id,
            title: c.title || `Cartón Oficial #${c.card_code}`,
            playerName: c.player_name || 'Jugador',
            playerPhone: c.player_phone || '',
            sellerName: receiptsMap[c.receipt_id]?.seller_name || 'Venta Oficial',
            paymentMethod: receiptsMap[c.receipt_id]?.payment_method || 'Confirmado',
            receiptStatus: receiptsMap[c.receipt_id]?.status || 'Aprobado',
            grid: c.grid,
            es_promo: c.es_promo,
            is_active: c.is_active
          }));
        }
      } catch (err) {
        console.error("Error al buscar en Supabase:", err);
      }
    }

    setIsLoading(false);
    setSearchResults(matched);

    if (matched.length === 1) {
      setSelectedCard(matched[0]);
    } else if (matched.length > 1) {
      setSelectedCard(matched[0]);
    } else {
      setSelectedCard(null);
      setNotFoundMsg(`No se encontró ningún cartón oficial con "${raw}". Verifica el código o teléfono.`);
    }
  }, [searchQuery, realRoomCards]);

  // Auditoría detallada del cartón seleccionado frente a las bolillas cantadas
  const audit = useMemo(() => {
    if (!selectedCard || !selectedCard.grid) return null;

    const grid = selectedCard.grid; // Matriz 3x9
    const rowsAudit = grid.map((row, rIdx) => {
      const numbers = row.filter(n => n !== null && n !== undefined);
      const matched = numbers.filter(n => calledSet.has(n));
      const missing = numbers.filter(n => !calledSet.has(n));
      const isComplete = numbers.length === 5 && matched.length === 5;
      return {
        rIdx: rIdx + 1,
        totalNumbers: numbers.length,
        numbers,
        matched,
        missing,
        isComplete,
        isNear: missing.length === 1 // A 1 número para línea
      };
    });

    const allNumbers = grid.flat().filter(n => n !== null && n !== undefined);
    const totalMatched = allNumbers.filter(n => calledSet.has(n));
    const totalMissing = allNumbers.filter(n => !calledSet.has(n));
    const isBingo = allNumbers.length === 15 && totalMatched.length === 15;
    const completedRows = rowsAudit.filter(r => r.isComplete);
    const hasLine = completedRows.length > 0;
    const isNearBingo = totalMissing.length === 1; // A 1 número del BINGO

    // Determinación del estado oficial
    let statusType = 'normal'; // 'bingo' | 'linea' | 'capilla' | 'incompleto'
    let statusTitle = '';
    let statusDesc = '';

    if (isBingo) {
      statusType = 'bingo';
      statusTitle = '👑 ¡¡BINGO VÁLIDO Y CONFIRMADO!!';
      statusDesc = `El cartón completó los 15 números oficiales (${totalMatched.length}/15). ¡Premio Mayor Confirmado!`;
    } else if (hasLine) {
      statusType = 'linea';
      const linesNames = completedRows.map(r => `Fila ${r.rIdx}`).join(' y ');
      statusTitle = `🎉 ¡¡LÍNEA VÁLIDA CONFIRMADA (${linesNames})!!`;
      statusDesc = `Completó 5 números en línea horizontal. Faltan ${totalMissing.length} números para Bingo.`;
    } else if (isNearBingo) {
      statusType = 'capilla';
      statusTitle = `⏳ ¡EN CAPILLA PARA BINGO (A 1 BOLILLA)!`;
      statusDesc = `Tiene 14 de 15 números acertados. Está esperando únicamente la bolilla #${totalMissing[0]}.`;
    } else if (rowsAudit.some(r => r.isNear)) {
      statusType = 'capilla';
      const nearRow = rowsAudit.find(r => r.isNear);
      statusTitle = `⏳ ¡EN CAPILLA PARA LÍNEA (Fila ${nearRow.rIdx})!`;
      statusDesc = `Tiene 4 de 5 números en la Fila ${nearRow.rIdx}. Esperando la bolilla #${nearRow.missing[0]}.`;
    } else {
      statusType = 'incompleto';
      const bestRow = Math.max(...rowsAudit.map(r => r.matched.length));
      statusTitle = `❌ NO ES GANADOR TODAVÍA`;
      statusDesc = `Tiene ${totalMatched.length} de 15 números acertados (faltan ${totalMissing.length}). Su mejor fila tiene ${bestRow}/5.`;
    }

    return {
      rowsAudit,
      allNumbers,
      totalMatched,
      totalMissing,
      isBingo,
      hasLine,
      completedRows,
      statusType,
      statusTitle,
      statusDesc
    };
  }, [selectedCard, calledSet]);

  // Proclamar ganador oficial
  const handleProclaim = (prizeType) => {
    if (!selectedCard || !audit) return;

    const isBingoPrize = prizeType === 'bingo';
    const amount = isBingoPrize ? roundBingoPrize : roundLineaPrize;
    const formattedAmount = `$${Number(amount).toLocaleString('es-AR')}`;
    const pName = selectedCard.playerName || 'Jugador';
    const cId = selectedCard.id || selectedCard.card_code;

    const announcement = {
      title: isBingoPrize 
        ? `👑 ¡¡BINGO CONFIRMADO EN PREMIO ${currentRound}!!` 
        : `🎉 ¡¡LÍNEA CONFIRMADA EN PREMIO ${currentRound}!!`,
      message: isBingoPrize
        ? `¡Cartón lleno de 15 números para ${pName} con el cartón oficial ${cId}!`
        : `¡Línea completa para ${pName} con el cartón oficial ${cId}!`,
      amount: formattedAmount,
      winnerName: pName,
      cardId: cId,
      prizeType: prizeType,
      timestamp: Date.now()
    };

    if (onDeclareWinner) {
      onDeclareWinner({
        prizeType,
        card: selectedCard,
        announcement,
        amount
      });
    }

    setAnnouncementSent({
      type: prizeType,
      text: `¡${isBingoPrize ? 'BINGO' : 'LÍNEA'} proclamado oficialmente por ${formattedAmount}! Notificado en pantalla y locución.`
    });
  };

  const containerStyle = isModal
    ? {
        position: 'fixed',
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        backgroundColor: 'rgba(0, 0, 0, 0.85)',
        backdropFilter: 'blur(8px)',
        zIndex: 99999,
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        padding: '16px',
        overflowY: 'auto'
      }
    : {
        width: '100%'
      };

  const cardBoxStyle = isModal
    ? {
        maxWidth: '840px',
        width: '100%',
        maxHeight: '92vh',
        overflowY: 'auto',
        background: 'linear-gradient(135deg, rgba(15, 23, 42, 0.98), rgba(30, 41, 59, 0.98))',
        border: '1.5px solid var(--accent-gold)',
        borderRadius: 'var(--radius-lg)',
        boxShadow: '0 20px 50px rgba(0, 0, 0, 0.8), 0 0 25px rgba(245, 158, 11, 0.25)',
        padding: '24px'
      }
    : {
        background: 'linear-gradient(135deg, rgba(15, 23, 42, 0.92), rgba(30, 41, 59, 0.92))',
        border: '1.5px solid rgba(245, 158, 11, 0.4)',
        borderRadius: 'var(--radius-lg)',
        boxShadow: '0 8px 30px rgba(0, 0, 0, 0.35)',
        padding: '20px'
      };

  return (
    <div style={containerStyle}>
      <div style={cardBoxStyle}>
        {/* Cabecera del Validador */}
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '16px', borderBottom: '1px solid rgba(255, 255, 255, 0.1)', paddingBottom: '12px' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
            <div style={{ width: '40px', height: '40px', borderRadius: '50%', background: 'linear-gradient(135deg, #f59e0b, #d97706)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '1.2rem', color: '#111827', fontWeight: '900', boxShadow: '0 4px 12px rgba(245, 158, 11, 0.35)' }}>
              <i className="fa-solid fa-stamp"></i>
            </div>
            <div>
              <h3 style={{ margin: 0, fontSize: '1.15rem', fontWeight: '900', color: '#ffffff', display: 'flex', alignItems: 'center', gap: '8px' }}>
                Validador Oficial de Cartones en Vivo
                <span className="brand-badge" style={{ backgroundColor: 'rgba(16, 185, 129, 0.2)', color: '#10b981', fontSize: '0.74rem' }}>
                  Locutor / Admin
                </span>
              </h3>
              <span style={{ fontSize: '0.78rem', color: 'var(--text-muted)' }}>
                Auditoría instantánea contra las {calledBalls.length} bolillas cantadas
              </span>
            </div>
          </div>

          {isModal && onClose && (
            <button
              type="button"
              className="btn btn-secondary btn-sm"
              onClick={onClose}
              style={{ width: '36px', height: '36px', padding: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}
            >
              <i className="fa-solid fa-xmark"></i>
            </button>
          )}
        </div>

        {/* Buscador Rápido de Cartón */}
        <form onSubmit={(e) => { e.preventDefault(); handleSearch(); }} style={{ marginBottom: '16px' }}>
          <div style={{ display: 'flex', gap: '8px' }}>
            <div style={{ position: 'relative', flex: 1 }}>
              <i className="fa-solid fa-magnifying-glass" style={{ position: 'absolute', left: '14px', top: '50%', transform: 'translateY(-50%)', color: 'var(--accent-gold)' }}></i>
              <input
                type="text"
                className="input-field"
                placeholder="Escribe N° de cartón (ej: 70196, CR-70196) o Teléfono del comprador..."
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
                style={{ width: '100%', paddingLeft: '40px', fontSize: '0.92rem' }}
                autoFocus={isModal}
              />
            </div>
            <button
              type="submit"
              className="btn btn-primary"
              disabled={isLoading || !searchQuery.trim()}
              style={{ padding: '10px 18px', fontWeight: '800', display: 'flex', alignItems: 'center', gap: '8px', background: 'linear-gradient(135deg, var(--accent-gold), #d97706)', color: '#111827', borderColor: 'var(--accent-gold)' }}
            >
              <i className={`fa-solid ${isLoading ? 'fa-spinner fa-spin' : 'fa-check-double'}`}></i>
              <span>{isLoading ? 'Buscando...' : 'Validar'}</span>
            </button>
            {searchQuery && (
              <button
                type="button"
                className="btn btn-secondary"
                onClick={() => { setSearchQuery(''); setSelectedCard(null); setSearchResults([]); setNotFoundMsg(''); }}
                style={{ padding: '10px 14px' }}
                title="Limpiar búsqueda"
              >
                <i className="fa-solid fa-eraser"></i>
              </button>
            )}
          </div>
        </form>

        {/* Mensaje de no encontrado */}
        {notFoundMsg && (
          <div style={{ padding: '10px 14px', background: 'rgba(239, 68, 68, 0.15)', border: '1px solid #ef4444', borderRadius: 'var(--radius-md)', color: '#fca5a5', fontSize: '0.85rem', marginBottom: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
            <i className="fa-solid fa-circle-exclamation"></i>
            <span>{notFoundMsg}</span>
          </div>
        )}

        {/* Múltiples resultados para el mismo comprador */}
        {searchResults.length > 1 && (
          <div style={{ marginBottom: '16px', background: 'rgba(255, 255, 255, 0.04)', padding: '10px 12px', borderRadius: 'var(--radius-md)', border: '1px solid rgba(255, 255, 255, 0.1)' }}>
            <span style={{ fontSize: '0.8rem', color: 'var(--text-muted)', display: 'block', marginBottom: '8px' }}>
              El jugador tiene <strong>{searchResults.length} cartones oficiales</strong>. Selecciona cuál validar:
            </span>
            <div style={{ display: 'flex', gap: '6px', flexWrap: 'wrap' }}>
              {searchResults.map((c, i) => {
                const isSelected = selectedCard?.id === c.id;
                return (
                  <button
                    key={c.id || i}
                    type="button"
                    className={`btn btn-sm ${isSelected ? 'btn-primary' : 'btn-secondary'}`}
                    onClick={() => setSelectedCard(c)}
                    style={{ fontSize: '0.78rem', padding: '5px 10px', fontWeight: '800' }}
                  >
                    Cartón #{c.id || c.card_code}
                  </button>
                );
              })}
            </div>
          </div>
        )}

        {/* RESULTADO DE VALIDACIÓN DEL CARTÓN SELECCIONADO */}
        {selectedCard && audit && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
            {/* 1. BANNER PRINCIPAL DE VEREDICTO */}
            <div style={{
              background: audit.statusType === 'bingo'
                ? 'linear-gradient(135deg, rgba(16, 185, 129, 0.25), rgba(6, 182, 212, 0.25))'
                : audit.statusType === 'linea'
                ? 'linear-gradient(135deg, rgba(245, 158, 11, 0.25), rgba(217, 119, 6, 0.25))'
                : audit.statusType === 'capilla'
                ? 'linear-gradient(135deg, rgba(139, 92, 246, 0.25), rgba(6, 182, 212, 0.25))'
                : 'linear-gradient(135deg, rgba(239, 68, 68, 0.15), rgba(15, 23, 42, 0.35))',
              border: `2px solid ${
                audit.statusType === 'bingo' ? '#10b981' :
                audit.statusType === 'linea' ? '#f59e0b' :
                audit.statusType === 'capilla' ? '#a855f7' : '#ef4444'
              }`,
              borderRadius: 'var(--radius-lg)',
              padding: '16px 20px',
              boxShadow: audit.statusType === 'bingo' ? '0 0 25px rgba(16, 185, 129, 0.35)' : undefined
            }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: '12px' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
                  <div style={{
                    width: '44px',
                    height: '44px',
                    borderRadius: '50%',
                    backgroundColor: audit.statusType === 'bingo' ? '#10b981' : audit.statusType === 'linea' ? '#f59e0b' : audit.statusType === 'capilla' ? '#a855f7' : '#ef4444',
                    color: '#ffffff',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    fontSize: '1.3rem',
                    fontWeight: '900'
                  }}>
                    {audit.statusType === 'bingo' && <i className="fa-solid fa-crown"></i>}
                    {audit.statusType === 'linea' && <i className="fa-solid fa-star"></i>}
                    {audit.statusType === 'capilla' && <i className="fa-solid fa-hourglass-half"></i>}
                    {audit.statusType === 'incompleto' && <i className="fa-solid fa-xmark"></i>}
                  </div>
                  <div>
                    <h4 style={{ margin: 0, fontSize: '1.15rem', fontWeight: '900', color: '#ffffff' }}>
                      {audit.statusTitle}
                    </h4>
                    <span style={{ fontSize: '0.86rem', color: 'var(--text-main)', marginTop: '2px', display: 'block', fontWeight: '600' }}>
                      {audit.statusDesc}
                    </span>
                  </div>
                </div>

                {/* Botones de acción del locutor si es ganador */}
                <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
                  {audit.hasLine && !audit.isBingo && (
                    <button
                      type="button"
                      className="btn"
                      onClick={() => handleProclaim('linea')}
                      style={{
                        padding: '10px 16px',
                        background: 'linear-gradient(135deg, #f59e0b, #d97706)',
                        borderColor: '#f59e0b',
                        color: '#111827',
                        fontWeight: '900',
                        fontSize: '0.88rem',
                        boxShadow: '0 4px 14px rgba(245, 158, 11, 0.4)',
                        display: 'flex',
                        alignItems: 'center',
                        gap: '6px'
                      }}
                    >
                      <i className="fa-solid fa-bullhorn"></i>
                      <span>Proclamar Ganador de LÍNEA (${Number(roundLineaPrize).toLocaleString('es-AR')})</span>
                    </button>
                  )}

                  {audit.isBingo && (
                    <button
                      type="button"
                      className="btn"
                      onClick={() => handleProclaim('bingo')}
                      style={{
                        padding: '10px 18px',
                        background: 'linear-gradient(135deg, #10b981, #059669)',
                        borderColor: '#10b981',
                        color: '#ffffff',
                        fontWeight: '900',
                        fontSize: '0.92rem',
                        boxShadow: '0 4px 18px rgba(16, 185, 129, 0.45)',
                        display: 'flex',
                        alignItems: 'center',
                        gap: '8px'
                      }}
                    >
                      <i className="fa-solid fa-trophy"></i>
                      <span>👑 Proclamar Ganador de BINGO (${Number(roundBingoPrize).toLocaleString('es-AR')})</span>
                    </button>
                  )}
                </div>
              </div>

              {announcementSent && (
                <div style={{ marginTop: '12px', padding: '8px 12px', background: 'rgba(16, 185, 129, 0.3)', border: '1px solid #10b981', borderRadius: 'var(--radius-sm)', color: '#ffffff', fontWeight: '800', fontSize: '0.84rem', display: 'flex', alignItems: 'center', gap: '6px' }}>
                  <i className="fa-solid fa-check-circle"></i>
                  <span>{announcementSent.text}</span>
                </div>
              )}
            </div>

            {/* 2. AUDITORÍA FILA POR FILA (Transparencia Total) */}
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: '10px' }}>
              {audit.rowsAudit.map(r => (
                <div
                  key={r.rIdx}
                  style={{
                    background: r.isComplete
                      ? 'rgba(16, 185, 129, 0.15)'
                      : r.isNear
                      ? 'rgba(245, 158, 11, 0.15)'
                      : 'rgba(255, 255, 255, 0.03)',
                    border: `1.5px solid ${r.isComplete ? '#10b981' : r.isNear ? '#f59e0b' : 'rgba(255, 255, 255, 0.1)'}`,
                    borderRadius: 'var(--radius-md)',
                    padding: '12px',
                    display: 'flex',
                    flexDirection: 'column',
                    gap: '6px'
                  }}
                >
                  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                    <span style={{ fontSize: '0.82rem', fontWeight: '800', color: r.isComplete ? '#10b981' : r.isNear ? '#f59e0b' : '#ffffff' }}>
                      Fila #{r.rIdx}
                    </span>
                    <span style={{ fontSize: '0.82rem', fontWeight: '900', color: r.isComplete ? '#10b981' : 'var(--text-muted)' }}>
                      {r.matched.length} / 5 {r.isComplete ? '✅ ¡LÍNEA!' : r.isNear ? '⚠️ A 1' : ''}
                    </span>
                  </div>

                  {/* Números de la fila */}
                  <div style={{ display: 'flex', gap: '4px', flexWrap: 'wrap', marginTop: '4px' }}>
                    {r.numbers.map(num => {
                      const isMatched = calledSet.has(num);
                      return (
                        <span
                          key={num}
                          style={{
                            display: 'inline-flex',
                            alignItems: 'center',
                            justifyContent: 'center',
                            width: '28px',
                            height: '26px',
                            borderRadius: '4px',
                            fontSize: '0.82rem',
                            fontWeight: '900',
                            backgroundColor: isMatched ? '#10b981' : 'rgba(255, 255, 255, 0.08)',
                            color: isMatched ? '#ffffff' : 'var(--text-muted)',
                            border: isMatched ? '1px solid #10b981' : '1px dashed rgba(255, 255, 255, 0.2)'
                          }}
                          title={isMatched ? `Bolilla #${num} Cantada` : `Bolilla #${num} Aún no cantada`}
                        >
                          {num}
                        </span>
                      );
                    })}
                  </div>
                </div>
              ))}
            </div>

            {/* 3. FICHA DEL COMPRADOR Y PROCEDENCIA */}
            <div style={{
              display: 'flex',
              justifyContent: 'space-between',
              alignItems: 'center',
              flexWrap: 'wrap',
              gap: '12px',
              padding: '12px 16px',
              background: 'rgba(255, 255, 255, 0.03)',
              borderRadius: 'var(--radius-md)',
              border: '1px solid rgba(255, 255, 255, 0.08)',
              fontSize: '0.86rem'
            }}>
              <div>
                <span style={{ color: 'var(--text-muted)' }}>Jugador: </span>
                <strong style={{ color: '#ffffff' }}>{selectedCard.playerName || 'Jugador Oficial'}</strong>
                {selectedCard.playerPhone && (
                  <span style={{ marginLeft: '10px', color: 'var(--accent-teal)' }}>
                    📞 {selectedCard.playerPhone}
                  </span>
                )}
              </div>

              <div>
                <span style={{ color: 'var(--text-muted)' }}>Vendedor: </span>
                <strong style={{ color: 'var(--accent-gold)' }}>{selectedCard.sellerName || 'Vendedor Oficial'}</strong>
                <span style={{ marginLeft: '12px', color: 'var(--accent-green)', fontWeight: '700' }}>
                  ✓ Pago Verificado
                </span>
              </div>

              {selectedCard.playerPhone && (
                <a
                  href={`https://wa.me/${selectedCard.playerPhone.replace(/[^0-9]/g, '')}`}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="btn btn-secondary btn-sm"
                  style={{ display: 'inline-flex', alignItems: 'center', gap: '6px', color: '#25D366', borderColor: '#25D366' }}
                >
                  <i className="fa-brands fa-whatsapp"></i> WhatsApp del Ganador
                </a>
              )}
            </div>

            {/* 4. PREVISUALIZACIÓN OFICIAL EN ROJO RUBÍ */}
            <div>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px' }}>
                <span style={{ fontSize: '0.82rem', fontWeight: '800', color: 'var(--text-muted)' }}>
                  Cartón Físico Oficial en Pantalla:
                </span>
                <span style={{ fontSize: '0.78rem', color: 'var(--accent-gold)' }}>
                  Serie Oficial: <strong>{selectedCard.id || selectedCard.card_code}</strong>
                </span>
              </div>

              <window.CartonView
                card={selectedCard}
                calledBalls={calledBalls}
                isLeaderRadar={false}
              />
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

window.CardValidator = CardValidator;
window.CardValidatorModal = CardValidator;
