const { useState, useEffect, useRef } = React;

window.Game3P = function Game3P({ socket, roomData, gameState, onLeave }) {
  const [myIndex, setMyIndex] = useState(0);
  const [toasts, setToasts] = useState([]);
  const [logs, setLogs] = useState([]);
  const [anims, setAnims] = useState([]); 
  const logsEndRef = useRef(null);
  
  const [targeting, setTargeting] = useState({ active: false, actionPayload: null }); 
  const [selectedNormalId, setSelectedNormalId] = useState(null); 
  const [showRules, setShowRules] = useState(false);
  const [drinkModal, setDrinkModal] = useState({ open: false, selectedIds: [] });
  const [swapModal, setSwapModal] = useState({ open: false, itemId: null, myCardId: null, cupCardId: null });
  const [peekModal, setPeekModal] = useState({ open: false, result: null });
  const [shareModal, setShareModal] = useState({ open: false, itemId: null, targetPlayerId: null, mySelectedIds: [] });
  const [shatterModal, setShatterModal] = useState({ open: false, itemId: null });
  const [toastItemModal, setToastItemModal] = useState({ open: false, card: null });
  const [screenFlash, setScreenFlash] = useState(null);

  useEffect(() => {
    if (!gameState) return;
    const pId = roomData?.player?.id || JSON.parse(sessionStorage.getItem('pb_session'))?.playerId;
    const idx = gameState.players.findIndex(p => p.id === pId);
    setMyIndex(idx >= 0 ? idx : 0);
  }, [gameState, roomData]);

  useEffect(() => setSelectedNormalId(null), [gameState?.currentPhase, gameState?.currentPlayerIndex]);

  useEffect(() => {
    const logHandler = (msg) => {
      const id = Date.now() + Math.random();
      setToasts(prev => [...prev, { id, msg }]);
      setTimeout(() => setToasts(prev => prev.filter(t => t.id !== id)), 3500);
      setLogs(prev => [...prev, { id, time: new Date().toLocaleTimeString('zh-CN', { hour12: false }), msg }]);
    };
    
    const animHandler = (data) => {
        const id = Date.now() + Math.random();
        setAnims(prev => [...prev, { id, ...data }]);
        
        const myId = roomData?.player?.id || JSON.parse(sessionStorage.getItem('pb_session'))?.playerId;
        if (data.type === 'stat' && data.targetId === myId) {
            if (data.damage > 0) setScreenFlash('red');
            else if (data.heal > 0) setScreenFlash('green');
            setTimeout(() => setScreenFlash(null), 1000);
        }
        
        if (window.AudioSystem) {
            if (data.isShake) window.AudioSystem.play('table_flip');
            else if (data.type === 'item') window.AudioSystem.play('item_use');
            else if (data.type === 'fail') window.AudioSystem.play('item_fail');
            else if (data.type === 'action_drink') window.AudioSystem.play('drink');
            else if (data.type === 'action_push_cup') window.AudioSystem.play('push_cup');
            else if (data.type === 'stat') {
                if (data.damage > 0) window.AudioSystem.play('damage');
                if (data.heal > 0) window.AudioSystem.play('heal');
                if (data.score > 0) window.AudioSystem.play('score');
                if (data.antidote) window.AudioSystem.play('antidote');
            }
        }
        setTimeout(() => setAnims(prev => prev.filter(a => a.id !== id)), ['item', 'fail', 'action_drink', 'action_push_cup', 'admire'].includes(data.type) ? 2000 : 2500); 
    };

    socket.on('gameLog', logHandler); socket.on('animEvent', animHandler);
    socket.on('peekResult', (data) => setPeekModal({ open: true, result: data }));
    return () => { socket.off('gameLog'); socket.off('animEvent'); socket.off('peekResult'); };
  }, [socket]);

  useEffect(() => {
    if (gameState?.winner) {
      if (gameState.winner === me?.id) window.AudioSystem?.play('win');
      else if (gameState.winner !== 'draw') window.AudioSystem?.play('lose');
    }
  }, [gameState?.winner, me?.id]);

  useEffect(() => { if (logsEndRef.current) logsEndRef.current.scrollIntoView({ behavior: 'smooth' }); }, [logs]);

  if (!gameState || !gameState.players) return <div className="text-white text-center mt-20">正在布置圆桌席位...</div>;
  
  const me = gameState.players[myIndex] || {};
  const opponents = gameState.players.filter(p => p.id !== me.id);
  const aliveOpponents = opponents.filter(p => p.hp > 0);
  const isMyTurn = gameState.currentPlayerIndex === myIndex;
  
  const isForcedToDrink = gameState.cupModifiers?.force || gameState.cupStack?.length >= gameState.mode;
  const isSettling = gameState.currentPhase === 'Settling';
  const isShaking = anims.some(a => a.isShake); 

  const activePlayer = gameState.players[gameState.currentPlayerIndex];
  const activePlayerDisplayName = isMyTurn ? `${me.name} (你)` : `${activePlayer?.name}${activePlayer?.isAI ? ' 🤖' : ''}`;

  const getPhaseStatusText = () => {
    if (gameState.currentPhase === 'Phase1_Toast') return `🥂 ${activePlayerDisplayName} 正在发起敬酒`;
    if (gameState.currentPhase === 'Phase2_Decision') return `🤔 ${activePlayerDisplayName} 正在接收抉择`;
    if (gameState.currentPhase === 'Settling') return `⚖️ 结算清点中...`;
    if (gameState.currentPhase === 'GameOver') return `🏁 对局结束`;
    return '...';
  };

  const renderFormattedText = (text, colorClass = "text-cyan-400") => {
    if (!gameState || !gameState.players || typeof text !== 'string') return text;
    const names = gameState.players.map(p => p.name).sort((a, b) => b.length - a.length);
    if (names.length === 0) return text;
    const escapedNames = names.map(n => n.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
    const regex = new RegExp(`(${escapedNames.join('|')})`, 'g');
    const parts = text.split(regex);
    return parts.map((part, i) => {
        if (names.includes(part)) {
            return <span key={i} className={`${colorClass} font-black drop-shadow-[0_0_2px_rgba(0,0,0,0.8)]`}>{part}</span>;
        }
        return part;
    });
  };

  const isCardPlayable = (card) => {
    if (gameState.winner) return false;
    if (isSettling) return card.type === 'item';
    const canPlayAsHidden = isMyTurn && (gameState.currentPhase === 'Phase1_Toast' || (gameState.currentPhase === 'Phase2_Decision' && !isForcedToDrink));

    if (card.type === 'item') {
      if (me.tipsyStatus) return canPlayAsHidden; 

      const eff = card.effectType;
      let canUseSkill = false;
      if (eff === 'swap') canUseSkill = me.hand.length >= 2 && gameState.cupStack.length > 0;
      else if (eff === 'steal') canUseSkill = true; 
      else if (eff === 'force') canUseSkill = gameState.cupStack.length > 0 && !gameState.cupModifiers?.force;
      else if (eff === 'peek') canUseSkill = isMyTurn && gameState.currentPhase === 'Phase2_Decision' && gameState.cupStack.length > 0;
      else if (eff === 'share') canUseSkill = isMyTurn && gameState.currentPhase === 'Phase2_Decision' && gameState.cupStack.length >= 2 && isForcedToDrink;
      else if (eff === 'intercept') canUseSkill = !isMyTurn && gameState.currentPhase === 'Phase2_Decision' && gameState.cupStack.length > 0;
      else canUseSkill = gameState.cupStack.length > 0;
      return canPlayAsHidden || canUseSkill;
    }
    return canPlayAsHidden;
  };

  const handleCardClick = (card) => {
     if (!isCardPlayable(card) || targeting.active) return;
     if (window.AudioSystem) window.AudioSystem.play('card_select', 0.6); 
     if (selectedNormalId === card.id) { setSelectedNormalId(null); return; }

     const isAnyTime = card.type === 'item' && ['steal', 'swap', 'double', 'shield', 'force', 'shatter'].includes(card.effectType);
     if (isAnyTime && (!isMyTurn || isSettling) && !me.tipsyStatus) {
         if (card.effectType === 'steal') {
             if (aliveOpponents.length === 1) socket.emit('playItemCard', { cardId: card.id, targetData: { targetPlayerId: aliveOpponents[0].id } });
             else setTargeting({ active: true, actionPayload: { type: 'playItemCard', cardId: card.id } });
         } else if (card.effectType === 'swap') {
             if (me.hand.length < 2) { setToasts(prev => [...prev, { id: Date.now(), msg: '❌ 必须有其他手牌才能替换！' }]); return; }
             setSwapModal({ open: true, itemId: card.id, myCardId: null, cupCardId: null });
         } else if (card.effectType === 'shatter') {
             if (gameState.cupStack.length === 0) { setToasts(prev => [...prev, { id: Date.now(), msg: '❌ 酒桌已空，无法使用！' }]); return; }
             if (gameState.cupStack.length === 1) {
                 socket.emit('playItemCard', { cardId: card.id, targetData: { targetCupCardId: gameState.cupStack[0].id } });
             } else {
                 setShatterModal({ open: true, itemId: card.id });
             }
         } else {
             socket.emit('playItemCard', { cardId: card.id });
         }
         return;
     }

     if (card.effectType === 'intercept' && !isMyTurn && !me.tipsyStatus) {
         socket.emit('playItemCard', { cardId: card.id });
         return;
     }

     if (card.type === 'item') { setToastItemModal({ open: true, card: card }); return; }
     
     if (gameState.currentPhase === 'Phase1_Toast') {
         if (window.AudioSystem) window.AudioSystem.play('card_slide'); 
         if (aliveOpponents.length === 1) socket.emit('playCard', { cardId: card.id, targetPlayerId: aliveOpponents[0].id });
         else setTargeting({ active: true, actionPayload: { type: 'playCard', cardId: card.id } });
     } else if (gameState.currentPhase === 'Phase2_Decision' && !isForcedToDrink) {
         setSelectedNormalId(card.id);
     }
  };

  const handleOpponentClick = (targetId) => {
      if (!targeting.active) return;
      const { type, cardId, baseCardId, itemId } = targeting.actionPayload;

      if (type === 'playCard') socket.emit('playCard', { cardId, targetPlayerId: targetId });
      else if (type === 'pushCup') socket.emit('pushCup', { baseCardId, targetPlayerId: targetId });
      else if (type === 'playItemCard') socket.emit('playItemCard', { cardId, targetData: { targetPlayerId: targetId } });
      else if (type === 'share_select_target') setShareModal({ open: true, itemId, targetPlayerId: targetId, mySelectedIds: [] });
      
      setTargeting({ active: false, actionPayload: null });
      setSelectedNormalId(null);
  };

  const handleDrinkClick = () => {
    if (gameState.cupStack.length === 1 || me.tipsyStatus) {
        socket.emit('drink', { selectedIds: gameState.cupStack.map(c => c.id) });
    } else {
        setDrinkModal({ open: true, selectedIds: [] });
    }
  };

  const renderStatAnims = (playerId) => {
    const myAnims = anims.filter(a => a.type === 'stat' && a.targetId === playerId);
    const tipsyAnim = anims.filter(a => a.type === 'tipsy' && a.targetId === playerId);
    return (
        <div className="absolute inset-0 pointer-events-none flex items-center justify-center z-50">
            {myAnims.map(a => (
                <div key={a.id} className="flex flex-col items-center gap-1 font-black text-3xl md:text-5xl tracking-wider" style={{ textShadow: '0 0 10px #000, 0 0 20px #000' }}>
                    {a.tipsy && <span className="text-pink-400 anim-tipsy drop-shadow-2xl mb-1 text-6xl">🌀</span>}
                    {a.antidote && <span className="text-blue-400 anim-float drop-shadow-2xl mb-1">✨ 解毒</span>}
                    {a.damage > 0 && <span className="text-red-500 anim-float drop-shadow-2xl mb-1">- {a.damage} 血</span>}
                    {a.heal > 0 && <span className="text-green-400 anim-float drop-shadow-2xl mb-1">+ {a.heal} 血</span>}
                    {a.score > 0 && <span className="text-yellow-400 anim-float drop-shadow-2xl">+ {a.score} 分</span>}
                </div>
            ))}
            {tipsyAnim.map(a => <div key={a.id} className="flex flex-col items-center font-black"><span className="text-pink-400 anim-tipsy drop-shadow-2xl text-7xl">🌀</span></div>)}
        </div>
    );
  };

  return (
    <div className={`h-[100dvh] w-full flex flex-col relative overflow-hidden bg-gradient-to-br from-[#1a1a2e] to-[#0f0f1a] ${isShaking ? 'shake-screen' : ''}`}>
      {screenFlash && <div className={`fixed inset-0 z-[9999] pointer-events-none ${screenFlash === 'red' ? 'flash-red' : 'flash-green'}`}></div>}
       <div className="fixed top-12 md:top-16 left-1/2 transform -translate-x-1/2 z-[120] flex flex-col gap-1.5 pointer-events-none w-[85vw] md:w-auto items-center">
        {toasts.map(t => <div key={t.id} className="bg-yellow-600 bg-opacity-90 px-5 py-2 md:px-8 md:py-3 rounded-full font-bold text-base md:text-lg toast-enter shadow-lg text-center whitespace-normal border border-yellow-500/50 leading-tight">{renderFormattedText(t.msg, 'text-red-600')}</div>)}
       </div>

       {targeting.active && (
          <div className="absolute inset-0 bg-black bg-opacity-70 z-40 flex flex-col items-center justify-center">
             <h2 className="text-lg md:text-3xl text-yellow-400 font-bold animate-pulse drop-shadow-lg text-center px-4 mb-6">👉 请点击想针对的对手头像框</h2>
             <button onClick={() => setTargeting({active: false})} className="px-6 py-2.5 bg-gray-600 rounded-full text-white text-sm font-bold cursor-pointer hover:bg-gray-500 shadow-lg z-50">取消选择</button>
          </div>
       )}

       <div className="flex justify-between items-center text-xs md:text-sm text-gray-400 bg-gray-900 p-2 md:p-3 z-50 shrink-0 border-b border-gray-800">
          <span>🔖 房间: {gameState.roomId} (3人)</span>
          <div className="flex gap-4">
             <button onClick={() => setShowRules(true)} className="hover:text-yellow-400 font-bold cursor-pointer">📖 规则</button>
             <button onClick={onLeave} className="hover:text-red-500 cursor-pointer">🚪 逃跑</button>
          </div>
       </div>

       <div className="flex justify-center z-[70] mt-2 mb-1 shrink-0">
          <div className="text-[11px] sm:text-sm md:text-lg font-bold text-red-400 tracking-widest drop-shadow-lg bg-gray-900 bg-opacity-90 border border-gray-700 px-4 py-1.5 rounded-full shadow-xl flex items-center gap-2 whitespace-nowrap">
              {getPhaseStatusText()}
          </div>
       </div>

       <div className="flex-1 relative flex min-h-0 px-2 sm:px-4">
           {/* 新增的内部 Flex 容器，将滚动内容与固定底部区域上下彻底隔离开 */}
           <div className="flex-1 flex flex-col relative min-w-0">
               
               {/* 上半部分：可滚动区域（仅包含对手和酒桌） */}
               <div className="flex-1 flex flex-col overflow-x-hidden overflow-y-auto custom-scrollbar pt-2 gap-2 sm:gap-4">
                   
                   <div className="flex justify-between items-start w-full gap-2 shrink-0">
                       {opponents.map((opp, idx) => {
                           const isTargetable = targeting.active && opp.hp > 0;
                           const isThisOppTurn = gameState.players[gameState.currentPlayerIndex]?.id === opp.id;
                           return (
                             <div key={opp.id} onClick={() => isTargetable && handleOpponentClick(opp.id)}
                               className={`flex-1 max-w-[280px] bg-gray-800 p-2 md:p-4 rounded-xl border-2 transition-all relative overflow-hidden
                                 ${isTargetable ? 'border-yellow-400 shadow-[0_0_20px_#facc15] cursor-pointer scale-105 z-50 ring-2 ring-yellow-400 animate-pulse' : (isThisOppTurn ? 'border-yellow-500 shadow-[0_0_15px_rgba(234,179,8,0.4)]' : 'border-gray-700')}
                                 ${opp.hp <= 0 ? 'grayscale opacity-70' : ''}`}
                             >
                                {opp.hp <= 0 && (
                                    <div className="absolute inset-0 bg-black bg-opacity-70 z-40 rounded-xl flex items-center justify-center backdrop-blur-[2px]">
                                        <div className="transform -rotate-12 border-4 border-red-600 px-4 md:px-6 py-2 rounded-xl text-red-600 font-black text-2xl md:text-4xl tracking-widest bg-black bg-opacity-80 shadow-[0_0_20px_rgba(220,38,38,0.8)]">
                                            已淘汰
                                        </div>
                                    </div>
                                )}

                                {renderStatAnims(opp.id)}
                                <h3 id={`player-name-${opp.id}`} className="font-bold text-white text-xs md:text-base mb-1 truncate">{opp.name} {opp.isAI && '🤖'} {opp.tipsyStatus && <span className="text-pink-400 font-bold ml-1">🌀微醺</span>}</h3>
                                <div className="flex gap-1.5 text-[10px] md:text-sm mb-1.5">
                                   <span className="text-red-400 font-bold">❤️ {opp.hp}</span>
                                   <span className="text-yellow-400 font-bold">🏆 {opp.score}/6</span>
                                </div>
                                <div className="flex gap-1 flex-wrap min-h-[32px] md:min-h-[48px]">
                                   {opp.hand.map((_, i) => <div key={i} className="w-5 h-8 md:w-8 md:h-12 card-back rounded border border-gray-600 shadow-sm"></div>)}
                                </div>
                             </div>
                           )
                       })}
                   </div>

                    <div className="flex flex-col items-center justify-center min-h-[140px] md:min-h-[220px] shrink-0 py-2 my-auto">
                       <div className="relative w-48 h-48 md:w-80 md:h-80 bg-red-900 bg-opacity-20 rounded-full border-4 border-red-900 flex flex-col items-center justify-center p-4 shadow-xl">
                          <div className="absolute -top-3.5 bg-gray-800 px-3 py-0.5 rounded-full border border-gray-700 shadow-md text-[9px] md:text-xs text-gray-400 font-bold">剩余: {gameState.deckCount} 张</div>
                          {gameState.cupStack.length === 0 ? <span className="text-gray-500 font-bold tracking-widest text-xs md:text-lg">酒桌已空</span> : 
                            <div className="flex flex-wrap justify-center gap-2 md:gap-3">
                                {gameState.cupStack.map((c, i) => (
                                    <div key={i} className={`relative overflow-hidden w-16 h-24 md:w-20 md:h-28 rounded-lg block ${window.getCardStyle(c)} shadow-md transition-all ${c.faceUp && c.drank === false ? 'opacity-40 grayscale scale-90' : ''}`}>
                                        {c.faceUp ? (
                                          <>
                                            <div className="absolute inset-0 flex items-center justify-center pb-3 md:pb-4">
                                               <span className="text-2xl md:text-3xl">{window.getCardIcon(c)}</span>
                                            </div>
                                            <div className="absolute bottom-0 w-full bg-black py-0.5 flex items-center justify-center">
                                               <span className="text-[10px] md:text-xs font-bold text-white truncate px-0.5">{c.name}</span>
                                            </div>
                                            {c.drank === false && (
                                                <div className="absolute inset-0 flex items-center justify-center bg-black bg-opacity-50">
                                                  <span className="text-white text-[10px] font-bold border border-white px-1 transform -rotate-12 bg-red-600 bg-opacity-80">未饮用</span>
                                                </div>
                                            )}
                                          </>
                                        ) : (
                                            <div className="absolute bottom-0 w-full bg-black py-0.5 flex items-center justify-center">
                                               <span className="text-[10px] md:text-xs font-bold text-gray-400 truncate px-0.5">{c.ownerName}</span>
                                            </div>
                                        )}
                                    </div>
                                ))}
                            </div>
                          }
                       </div>
                   </div>

               </div> {/* 滚动区结束 */}

               {/* 下半部分：固定玩家区域（完全独立于滚动区，始终完美贴在视口底部） */}
               <div className="w-full flex justify-center shrink-0 z-20 pt-2 pb-2">
                   <div className={`bg-gray-800 p-2 md:p-6 rounded-xl border-2 w-full max-w-[700px] transition-all relative overflow-hidden ${isMyTurn ? 'border-yellow-500 shadow-[0_0_20px_rgba(234,179,8,0.3)]' : 'border-gray-700'} ${me.hp <= 0 ? 'grayscale opacity-70' : ''}`}>
                       {me.hp <= 0 && (
                            <div className="absolute inset-0 bg-black bg-opacity-70 z-40 rounded-xl flex items-center justify-center backdrop-blur-[2px]">
                                <div className="transform -rotate-12 border-4 border-red-600 px-6 py-3 rounded-xl text-red-600 font-black text-3xl md:text-5xl tracking-widest bg-black bg-opacity-80 shadow-[0_0_20px_rgba(220,38,38,0.8)]">
                                    已淘汰
                                </div>
                            </div>
                       )}

                       {renderStatAnims(me.id)}
                       <div className="flex justify-between items-center mb-2">
                           <h3 id={`player-name-${me.id}`} className="font-bold text-yellow-400 text-sm md:text-xl truncate mr-2">{me.name} (你) {me.tipsyStatus && <span className="text-pink-400 font-bold ml-1">🌀微醺</span>}</h3>
                           <div className="flex gap-2 shrink-0 text-xs md:text-sm">
                               <span className="text-red-400 font-bold bg-gray-900 px-2 py-0.5 rounded-full shadow-inner">❤️ {me.hp}</span>
                               <span className="text-yellow-400 font-bold bg-gray-900 px-2 py-0.5 rounded-full shadow-inner">🏆 {me.score}/6</span>
                           </div>
                       </div>
                        <div className="flex gap-2 md:gap-3 justify-center mb-3 flex-wrap min-h-[96px] md:min-h-[112px]">
                          {me.hand.map(c => {
                              const playable = isCardPlayable(c);
                              const isSelected = selectedNormalId === c.id || targeting.actionPayload?.cardId === c.id || targeting.actionPayload?.baseCardId === c.id;
                              return (
                              <div key={c.id} onClick={() => handleCardClick(c)} className={`card relative w-16 h-24 md:w-20 md:h-28 rounded-lg md:rounded-xl cursor-pointer shadow-lg block ${window.getCardStyle(c)} ${(me.hp <= 0 || !playable) ? 'disabled' : ''} ${isSelected ? 'selected' : ''}`}>
                                  <div className="absolute inset-0 flex items-center justify-center pb-3 md:pb-4">
                                      <span className="text-2xl md:text-3xl">{window.getCardIcon(c)}</span>
                                  </div>
                                  <div className="absolute bottom-0 w-full bg-black py-0.5 flex items-center justify-center">
                                      <span className="text-[10px] md:text-xs font-bold text-white truncate px-0.5">{c.name}</span>
                                  </div>
                              </div>
                          )})}
                       </div>
                       
                       {gameState.currentPhase === 'Phase2_Decision' && isMyTurn && !targeting.active && (
                          <div className="flex gap-2 md:gap-4 justify-center mt-2 md:mt-4">
                              <button onClick={handleDrinkClick} className="px-4 md:px-10 py-1.5 md:py-3 bg-red-700 hover:bg-red-600 text-white font-bold rounded-lg shadow-lg transition-colors text-xs md:text-base cursor-pointer">一饮而下！</button>
                              <button onClick={() => { if(selectedNormalId) { if (window.AudioSystem) window.AudioSystem.play('card_slide'); if (aliveOpponents.length === 1) socket.emit('pushCup', { baseCardId: selectedNormalId, targetPlayerId: aliveOpponents[0].id }); else setTargeting({ active: true, actionPayload: { type: 'pushCup', baseCardId: selectedNormalId } }); } }} disabled={isForcedToDrink || !selectedNormalId} className={`px-4 md:px-8 py-1.5 md:py-3 rounded-lg font-bold shadow-lg transition-colors text-xs md:text-base ${!isForcedToDrink && selectedNormalId ? 'bg-blue-700 hover:bg-blue-600 text-white cursor-pointer' : 'bg-gray-700 text-gray-500 cursor-not-allowed'}`}>添酒推杯</button>
                          </div>
                       )}
                   </div>
               </div>

           </div>

           <div className="hidden lg:flex w-72 lg:w-80 bg-gray-900 border-l border-gray-700 flex-col overflow-hidden shrink-0 shadow-lg relative z-[110]">
              <div className="p-4 bg-gray-800 flex justify-between items-center border-b border-gray-700 shadow-md">
                  <span className="font-bold text-yellow-500">📜 日志</span>
              </div>
              <div className="flex-1 p-4 overflow-y-auto space-y-3 text-sm text-gray-300 custom-scrollbar">
                {logs.map(log => <div key={log.id} className="border-b border-gray-800 pb-2"><span className="text-gray-500 font-mono text-xs">[{log.time}]</span> <br/>{renderFormattedText(log.msg)}</div>)}
                <div ref={logsEndRef} />
              </div>
           </div>
       </div>

       <div className="fixed inset-0 z-[100] flex flex-row flex-wrap items-center justify-center gap-4 pointer-events-none p-4">
        {anims.filter(a => ['item', 'fail', 'action_drink', 'action_push_cup', 'admire'].includes(a.type)).map(a => {
            const sourceName = gameState.players.find(p => p.id === a.sourceId)?.name || '未知';
            
            if (a.type === 'action_push_cup') {
                const targetName = gameState.players.find(p => p.id === a.targetId)?.name || '未知';
                return <window.FlyingCupAnim key={a.id} sourceId={a.sourceId} targetId={a.targetId} sourceName={sourceName} targetName={targetName} />;
            }

            if (a.type === 'admire') {
                return (
                    <div key={a.id} className="cinematic-enter bg-yellow-900 bg-opacity-95 border-4 border-yellow-400 p-6 rounded-3xl flex flex-col items-center shadow-[0_0_80px_rgba(250,204,21,0.8)] min-w-[240px] shrink-0">
                        <span className="text-6xl mb-2">🌟</span>
                        <h2 className="text-2xl text-white font-bold mb-2">全场赞赏</h2>
                        <h2 className="text-3xl text-yellow-400 font-black tracking-widest" style={{ textShadow: '0 4px 10px rgba(0,0,0,0.8)' }}>连尽三杯！</h2>
                    </div>
                );
            }

            if (a.type === 'item') {
                const targetName = a.targetId ? gameState.players.find(p => p.id === a.targetId)?.name : null;
                return (
                    <div key={a.id} className="cinematic-enter bg-gray-900 bg-opacity-95 border-2 border-yellow-500 p-4 md:p-6 rounded-2xl md:rounded-3xl flex flex-col items-center shadow-[0_0_50px_rgba(234,179,8,0.5)] min-w-[180px] md:min-w-[240px] shrink-0">
                        <h2 className="text-base md:text-2xl text-white font-bold mb-2 md:mb-4"><span className="text-cyan-400 font-black">{sourceName}</span> 发动了</h2>
                        <div className={`relative overflow-hidden w-20 h-28 md:w-32 md:h-48 rounded-xl block shadow-2xl ${window.getCardStyle({...a.card, faceUp: true})}`}>
                            <div className="absolute inset-0 flex items-center justify-center pb-4 md:pb-6">
                               <span className="text-4xl md:text-6xl">{window.getCardIcon({...a.card, faceUp: true})}</span>
                            </div>
                            <div className="absolute bottom-0 w-full bg-black py-1 flex items-center justify-center">
                               <span className="text-xs md:text-sm font-bold text-white truncate px-1">{a.card.name}</span>
                            </div>
                        </div>
                        {targetName && <h2 className="text-base md:text-2xl text-red-400 font-bold mt-2 md:mt-4">👉 目标: <span className="text-cyan-400 font-black">{targetName}</span></h2>}
                    </div>
                );
            }
            if (a.type === 'fail') {
                return (
                    <div key={a.id} className="cinematic-fail bg-gray-900 bg-opacity-95 border-2 border-gray-600 p-4 md:p-6 rounded-2xl md:rounded-3xl flex flex-col items-center shadow-[0_0_50px_rgba(0,0,0,0.8)] grayscale min-w-[180px] md:min-w-[240px] shrink-0">
                        <h2 className="text-base md:text-2xl text-gray-400 font-bold mb-2 md:mb-4"><span className="text-cyan-400 font-black">{sourceName}</span> 手滑了！</h2>
                        <div className={`relative overflow-hidden w-20 h-28 md:w-32 md:h-48 rounded-xl block shadow-2xl ${window.getCardStyle({...a.card, faceUp: true})} opacity-50 transform rotate-12`}>
                            <div className="absolute inset-0 flex items-center justify-center pb-4 md:pb-6">
                               <span className="text-4xl md:text-6xl">❌</span>
                            </div>
                            <div className="absolute bottom-0 w-full bg-black py-1 flex items-center justify-center">
                               <span className="text-xs md:text-sm font-bold text-white truncate px-1">{a.card.name}</span>
                            </div>
                        </div>
                        <h2 className="text-sm md:text-xl text-red-500 font-bold mt-2 md:mt-4">{a.reason || '动作慢半拍，道具被退回！'}</h2>
                    </div>
                );
            }
            if (a.type === 'action_drink') {
                return (
                    <div key={a.id} className="anim-gulp bg-red-900 bg-opacity-90 border-4 border-red-500 p-4 md:p-6 rounded-3xl flex flex-col items-center shadow-[0_0_80px_rgba(220,38,38,0.8)] min-w-[180px] md:min-w-[240px] shrink-0">
                        <h2 className="text-lg md:text-2xl text-white font-bold mb-2"><span className="text-cyan-400 font-black">{sourceName}</span> 端起 {a.count} 杯酒</h2>
                        <div className="w-20 h-20 md:w-32 md:h-32 my-2 sprite-drink rounded-2xl shadow-inner border border-red-500/20 bg-black/30"></div>
                        <h2 className="text-2xl md:text-4xl text-yellow-400 font-black tracking-widest" style={{ textShadow: '0 4px 10px rgba(0,0,0,0.8)' }}>一饮而尽！</h2>
                    </div>
                );
            }
            return null;
        })}
      </div>

      {showRules && <window.RulesModal onClose={() => setShowRules(false)} />}

       {toastItemModal.open && toastItemModal.card && (() => {
        const c = toastItemModal.card;
        const phase1 = gameState.currentPhase === 'Phase1_Toast';
        const phase2 = gameState.currentPhase === 'Phase2_Decision';
        let canSkill = false, skillReason = "";
        let canCover = phase1 || (phase2 && !isForcedToDrink);

        if (me.tipsyStatus) { canSkill = false; skillReason = "微醺期间不可使用"; }
        else {
            if (c.effectType === 'double') { canSkill = gameState.cupStack.length > 0; if(!canSkill) skillReason = "酒桌上无酒"; }
            else if (c.effectType === 'shield') { canSkill = gameState.cupStack.length > 0; if(!canSkill) skillReason = "无需掀桌"; }
            else if (c.effectType === 'steal') { canSkill = true; } 
            else if (c.effectType === 'swap') { canSkill = me.hand.length >= 2 && gameState.cupStack.length > 0; if(!canSkill) skillReason = "条件不足"; }
            else if (c.effectType === 'peek') { canSkill = phase2 && gameState.cupStack.length > 0; if(!canSkill) skillReason = "无毒可验"; }
            else if (c.effectType === 'force') { canSkill = gameState.cupStack.length > 0 && !gameState.cupModifiers?.force; if(!canSkill) skillReason = "已被锁定"; }
            else if (c.effectType === 'shatter') { canSkill = gameState.cupStack.length > 0; if(!canSkill) skillReason = "酒桌上无酒"; }
            else if (c.effectType === 'share') { canSkill = phase2 && isForcedToDrink && gameState.cupStack.length >= 2; if(!canSkill) skillReason = "未被强制饮酒或酒少于2杯"; }
            else if (c.effectType === 'intercept') { canSkill = !isMyTurn && phase2 && gameState.cupStack.length > 0; if(!canSkill) skillReason = "只能拦截对手"; }
        }

        return (
          <div className="fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-[99999] p-4">
            <div className="bg-gray-800 p-5 md:p-6 rounded-2xl border border-yellow-600 max-w-[280px] md:max-w-sm w-full text-center shadow-2xl modal-pop">
              <h3 className="text-lg md:text-xl text-yellow-500 font-bold mb-3">抉择时刻</h3>
              <p className="text-gray-300 mb-4 text-xs md:text-sm">如何使用【{c.name}】？</p>
              <div className="flex gap-3 flex-col">
                <div className="relative w-full group">
                    <button onClick={() => { 
                        if(c.effectType === 'swap') {
                            setSwapModal({open:true, itemId:c.id, myCardId:null, cupCardId:null}); 
                        } else if (c.effectType === 'steal') {
                            if (aliveOpponents.length === 1) socket.emit('playItemCard', { cardId: c.id, targetData: { targetPlayerId: aliveOpponents[0].id } });
                            else setTargeting({ active: true, actionPayload: { type: 'playItemCard', cardId: c.id } });
                        } else if (c.effectType === 'share') {
                            if (aliveOpponents.length === 1) setShareModal({open:true, itemId:c.id, targetPlayerId:aliveOpponents[0].id, mySelectedIds:[]});
                            else setTargeting({ active: true, actionPayload: { type: 'share_select_target', itemId: c.id } });
                        } else if (c.effectType === 'shatter') {
                            if (gameState.cupStack.length === 1) {
                                socket.emit('playItemCard', { cardId: c.id, targetData: { targetCupCardId: gameState.cupStack[0].id } });
                            } else {
                                setShatterModal({open:true, itemId:c.id});
                            }
                        } else {
                            socket.emit('playItemCard', {cardId:c.id}); 
                        }
                        setToastItemModal({open:false, card:null}); 
                    }} disabled={!canSkill} className={`w-full py-2.5 rounded font-bold text-sm md:text-base transition-colors ${canSkill ? 'bg-yellow-600 hover:bg-yellow-500 text-black shadow-lg cursor-pointer' : 'bg-gray-700 text-gray-500 cursor-not-allowed border border-gray-600'}`}>
                      🗡️ 发动技能
                    </button>
                    {!canSkill && skillReason && (
                        <div className="absolute top-[-25px] left-1/2 transform -translate-x-1/2 bg-black text-[10px] text-red-400 px-2 py-1 rounded hidden group-hover:block w-max z-50">{skillReason}</div>
                    )}
                </div>
                <button onClick={() => { 
                    if (phase1) {
                        if (window.AudioSystem) window.AudioSystem.play('card_slide');
                        if (aliveOpponents.length === 1) socket.emit('playCard', { cardId: c.id, targetPlayerId: aliveOpponents[0].id });
                        else setTargeting({ active: true, actionPayload: { type: 'playCard', cardId: c.id } });
                    }
                    else setSelectedNormalId(c.id); 
                    setToastItemModal({open:false, card:null}); 
                }} disabled={!canCover} className={`w-full py-2.5 rounded font-bold text-sm md:text-base transition-colors ${canCover ? 'bg-blue-700 hover:bg-blue-600 text-white shadow-lg cursor-pointer' : 'bg-gray-700 text-gray-500 cursor-not-allowed border border-gray-600'}`}>
                    {phase1 ? "🍷 盖伏暗牌 (敬酒)" : "🍷 选作暗牌 (推杯)"}
                </button>
                <button onClick={() => setToastItemModal({open:false, card:null})} className="w-full py-2 mt-1 bg-gray-600 hover:bg-gray-500 text-white font-bold text-sm rounded transition-colors cursor-pointer">取消</button>
              </div>
            </div>
          </div>
        );
      })()}

       {drinkModal.open && (
        <div className="fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-[99999] p-4">
          <div className="bg-gray-800 p-5 md:p-6 rounded-2xl border border-red-600 max-w-sm w-full text-center shadow-2xl modal-pop">
            <h3 className="text-lg md:text-xl text-red-500 font-bold mb-3">🍷 饮酒抉择</h3>
            <p className="text-xs md:text-sm text-gray-300 mb-3">请选择你要喝下的牌（至少选择1杯）：</p>
            <div className="flex gap-2 md:gap-4 mb-6 justify-center flex-wrap bg-gray-900 p-4 rounded-xl">
              {gameState.cupStack.map(c => {
                const isSelected = drinkModal.selectedIds.includes(c.id);
                return (
                  <div key={c.id} onClick={() => setDrinkModal(p => ({...p, selectedIds: p.selectedIds.includes(c.id) ? p.selectedIds.filter(id => id !== c.id) : [...p.selectedIds, c.id]}))} className={`relative overflow-hidden w-14 h-20 md:w-20 md:h-28 rounded-lg block cursor-pointer border-2 transition-transform hover:scale-105 ${window.getCardStyle(c)} ${isSelected ? 'ring-4 ring-red-500 scale-110 shadow-[0_0_15px_rgba(239,68,68,0.6)]' : 'opacity-70'}`}>
                    {c.faceUp ? (
                       <>
                         <div className="absolute inset-0 flex items-center justify-center pb-3 md:pb-4">
                            <span className="text-2xl md:text-3xl">{window.getCardIcon(c)}</span>
                         </div>
                         <div className="absolute bottom-0 w-full bg-black py-0.5 flex items-center justify-center">
                            <span className="text-[10px] md:text-xs font-bold text-white truncate px-0.5">{c.name}</span>
                         </div>
                       </>
                    ) : (
                       <div className="absolute bottom-0 w-full bg-black py-0.5 flex items-center justify-center">
                          <span className="text-[10px] md:text-xs font-bold text-gray-400 truncate px-0.5">{c.ownerName}</span>
                       </div>
                    )}
                  </div>
                );
              })}
            </div>
            <div className="flex gap-3 md:gap-4">
              <button onClick={() => setDrinkModal({open:false, selectedIds:[]})} className="flex-1 py-2.5 bg-gray-600 hover:bg-gray-500 text-white rounded font-bold text-sm transition-colors cursor-pointer">再想想</button>
              <button onClick={() => { socket.emit('drink', { selectedIds: drinkModal.selectedIds }); setDrinkModal({open: false, selectedIds: []}); }} disabled={drinkModal.selectedIds.length === 0} className={`flex-1 py-2.5 rounded font-bold text-white text-sm transition-colors ${drinkModal.selectedIds.length > 0 ? 'bg-red-600 hover:bg-red-500 cursor-pointer' : 'bg-gray-700 opacity-50 cursor-not-allowed'}`}>确认喝下</button>
            </div>
          </div>
        </div>
       )}

       {swapModal.open && (
        <div className="fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-[99999] p-4">
          <div className="bg-gray-800 p-5 md:p-6 rounded-2xl border border-yellow-600 max-w-sm w-full shadow-2xl modal-pop">
            <h3 className="text-lg md:text-xl text-yellow-500 font-bold text-center mb-3">🎭 偷天换日</h3>
            <p className="text-xs md:text-sm text-gray-300 mb-2 font-bold">1. 选桌上的牌：</p>
            <div className="flex gap-2 mb-3 justify-center bg-gray-900 p-3 rounded-lg">
              {gameState.cupStack.map(c => (
                <div key={c.id} onClick={() => setSwapModal(p => ({...p, cupCardId: c.id}))} className={`relative overflow-hidden w-12 h-16 md:w-16 md:h-24 rounded block border ${swapModal.cupCardId === c.id ? 'border-yellow-400 scale-110 shadow-[0_0_15px_rgba(250,204,21,0.6)]' : 'border-gray-600 card-back'} cursor-pointer transition-transform hover:scale-105`}>
                  {c.faceUp ? (
                     <>
                       <div className="absolute inset-0 flex items-center justify-center pb-3 md:pb-4">
                          <span className="text-xl md:text-2xl">{window.getCardIcon(c)}</span>
                       </div>
                       <div className="absolute bottom-0 w-full bg-black py-0.5 flex items-center justify-center">
                          <span className="text-[9px] md:text-xs font-bold text-white truncate px-0.5">{c.name}</span>
                       </div>
                     </>
                  ) : (
                     <div className="absolute bottom-0 w-full bg-black py-0.5 flex items-center justify-center">
                        <span className="text-[9px] text-gray-400 truncate px-0.5">{c.ownerName}</span>
                     </div>
                  )}
                </div>
              ))}
            </div>
            <p className="text-xs md:text-sm text-gray-300 mb-2 font-bold">2. 选自己的牌：</p>
            <div className="flex gap-2 mb-4 justify-center flex-wrap bg-gray-900 p-3 rounded-lg max-h-[30vh] overflow-y-auto custom-scrollbar">
              {me.hand.filter(c => c.id !== swapModal.itemId).map(c => (
                <div key={c.id} onClick={() => setSwapModal(p => ({...p, myCardId: c.id}))} className={`relative overflow-hidden w-12 h-16 md:w-16 md:h-24 rounded block cursor-pointer transition-transform hover:scale-105 ${window.getCardStyle(c)} ${swapModal.myCardId === c.id ? 'ring-2 ring-yellow-400 scale-110' : ''}`}>
                  <div className="absolute inset-0 flex items-center justify-center pb-3 md:pb-4">
                     <span className="text-xl md:text-2xl">{window.getCardIcon(c)}</span>
                  </div>
                  <div className="absolute bottom-0 w-full bg-black py-0.5 flex items-center justify-center">
                     <span className="text-[9px] md:text-xs font-bold text-white truncate px-0.5">{c.name}</span>
                  </div>
                </div>
              ))}
            </div>
            <div className="flex gap-3">
              <button onClick={() => setSwapModal({open:false})} className="flex-1 py-2.5 bg-gray-600 hover:bg-gray-500 text-white rounded font-bold text-sm transition-colors cursor-pointer">取消</button>
              <button onClick={() => { socket.emit('playItemCard', { cardId: swapModal.itemId, targetData: { targetHandCardId: swapModal.myCardId, targetCupCardId: swapModal.cupCardId } }); setSwapModal({open:false}); }} className="flex-1 py-2.5 bg-yellow-600 hover:bg-yellow-500 text-black rounded font-bold text-sm transition-colors cursor-pointer">确认偷换</button>
            </div>
          </div>
        </div>
       )}

       {peekModal.open && peekModal.result && (
        <div className="fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-[99999] p-4">
          <div className="bg-gray-800 p-5 md:p-6 rounded-2xl border border-blue-500 max-w-sm w-full text-center shadow-2xl modal-pop">
            <h3 className="text-lg md:text-xl text-blue-400 font-bold mb-3">🪡 银针试毒</h3>
            <div className="flex gap-2 justify-center flex-wrap mb-5 bg-gray-900 p-4 rounded-xl w-full">
              {peekModal.result.map((c, idx) => (
                <div key={idx} className={`relative overflow-hidden w-14 h-20 md:w-20 md:h-28 rounded-xl block border-2 ${window.getCardStyle({...c, faceUp: true})}`}>
                  <div className="absolute inset-0 flex items-center justify-center pb-3 md:pb-4">
                     <span className="text-2xl md:text-3xl">{window.getCardIcon({...c, faceUp: true})}</span>
                  </div>
                  <div className="absolute bottom-0 w-full bg-black py-0.5 flex items-center justify-center">
                     <span className="text-[10px] md:text-xs font-bold text-white truncate px-0.5">{c.name}</span>
                  </div>
                </div>
              ))}
            </div>
            <button onClick={() => setPeekModal({open:false, result: null})} className="w-full py-2.5 bg-blue-600 hover:bg-blue-500 text-white rounded-xl font-bold text-sm transition-colors cursor-pointer">了然于胸</button>
          </div>
        </div>
       )}

      {shareModal.open && (
        <div className="fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-[99999] p-4">
          <div className="bg-gray-800 p-5 md:p-6 rounded-2xl border border-purple-500 max-w-sm w-full text-center shadow-2xl modal-pop">
            <h3 className="text-lg md:text-xl text-purple-400 font-bold mb-3">🍶 同甘共苦</h3>
            <p className="text-xs md:text-sm text-gray-300 mb-3">选择【你】要喝下的酒（至少给对手留1杯）：</p>
            <div className="flex gap-2 md:gap-4 mb-6 justify-center flex-wrap bg-gray-900 p-4 rounded-xl">
              {gameState.cupStack.map(c => {
                const isSelected = shareModal.mySelectedIds.includes(c.id);
                return (
                  <div key={c.id} onClick={() => setShareModal(p => ({...p, mySelectedIds: p.mySelectedIds.includes(c.id) ? p.mySelectedIds.filter(id => id !== c.id) : [...p.mySelectedIds, c.id]}))} className={`relative overflow-hidden w-14 h-20 md:w-20 md:h-28 rounded-lg block cursor-pointer border-2 transition-transform hover:scale-105 ${window.getCardStyle(c)} ${isSelected ? 'ring-4 ring-purple-500 scale-110 shadow-[0_0_15px_rgba(168,85,247,0.6)]' : 'opacity-70'}`}>
                    {c.faceUp ? (
                       <>
                         <div className="absolute inset-0 flex items-center justify-center pb-3 md:pb-4">
                            <span className="text-2xl md:text-3xl">{window.getCardIcon(c)}</span>
                         </div>
                         <div className="absolute bottom-0 w-full bg-black py-0.5 flex items-center justify-center">
                            <span className="text-[10px] md:text-xs font-bold text-white truncate px-0.5">{c.name}</span>
                         </div>
                       </>
                    ) : (
                       <div className="absolute bottom-0 w-full bg-black py-0.5 flex items-center justify-center">
                          <span className="text-[10px] md:text-xs font-bold text-gray-400 truncate px-0.5">{c.ownerName}</span>
                       </div>
                    )}
                  </div>
                );
              })}
            </div>
            <div className="flex gap-3 md:gap-4">
              <button onClick={() => setShareModal({open:false, itemId: null, targetPlayerId: null, mySelectedIds:[]})} className="flex-1 py-2.5 bg-gray-600 hover:bg-gray-500 text-white rounded font-bold text-sm transition-colors cursor-pointer">取消</button>
              <button onClick={() => { 
                  socket.emit('playItemCard', { cardId: shareModal.itemId, targetData: { targetPlayerId: shareModal.targetPlayerId, mySelectedIds: shareModal.mySelectedIds } }); 
                  setShareModal({open: false, itemId: null, targetPlayerId: null, mySelectedIds: []}); 
              }} disabled={shareModal.mySelectedIds.length === 0 || shareModal.mySelectedIds.length >= gameState.cupStack.length} className={`flex-1 py-2.5 rounded font-bold text-white text-sm transition-colors ${shareModal.mySelectedIds.length > 0 && shareModal.mySelectedIds.length < gameState.cupStack.length ? 'bg-purple-600 hover:bg-purple-500 cursor-pointer' : 'bg-gray-700 opacity-50 cursor-not-allowed'}`}>确认分配</button>
            </div>
          </div>
        </div>
      )}

      {/* 碎盏指定目标弹窗 */}
      {shatterModal.open && (
        <div className="fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-[99999] p-4">
          <div className="bg-gray-800 p-5 md:p-6 rounded-2xl border border-gray-400 max-w-sm w-full text-center shadow-2xl modal-pop">
            <h3 className="text-lg md:text-xl text-gray-300 font-bold mb-3">🔨 碎盏</h3>
            <p className="text-xs md:text-sm text-gray-300 mb-3">请选择你要敲碎的酒：</p>
            <div className="flex gap-2 md:gap-4 mb-6 justify-center flex-wrap bg-gray-900 p-4 rounded-xl">
              {gameState.cupStack.map(c => (
                <div key={c.id} onClick={() => {
                    socket.emit('playItemCard', { cardId: shatterModal.itemId, targetData: { targetCupCardId: c.id } });
                    setShatterModal({open: false, itemId: null});
                }} className={`relative overflow-hidden w-14 h-20 md:w-20 md:h-28 rounded-lg block cursor-pointer border-2 transition-transform hover:scale-105 ${window.getCardStyle(c)} opacity-90 hover:ring-2 ring-gray-400`}>
                   {c.faceUp ? (
                     <>
                       <div className="absolute inset-0 flex items-center justify-center pb-3 md:pb-4">
                          <span className="text-2xl md:text-3xl">{window.getCardIcon(c)}</span>
                       </div>
                       <div className="absolute bottom-0 w-full bg-black py-0.5 flex items-center justify-center">
                          <span className="text-[10px] md:text-xs font-bold text-white truncate px-0.5">{c.name}</span>
                       </div>
                     </>
                   ) : (
                     <div className="absolute bottom-0 w-full bg-black py-0.5 flex items-center justify-center">
                        <span className="text-[10px] md:text-xs font-bold text-gray-400 truncate px-0.5">{c.ownerName}</span>
                     </div>
                   )}
                </div>
              ))}
            </div>
            <button onClick={() => setShatterModal({open:false, itemId: null})} className="w-full py-2.5 bg-gray-600 hover:bg-gray-500 text-white rounded font-bold text-sm transition-colors cursor-pointer">取消</button>
          </div>
        </div>
      )}

       {gameState.winner && (
        <div className="fixed inset-0 bg-black bg-opacity-95 flex flex-col items-center justify-center z-[99999] p-4">
          <h1 className="text-4xl md:text-6xl font-bold mb-4 text-white text-center leading-tight">{gameState.winner === me.id ? '🏆 赢家！' : '结束了...'}</h1>
          {gameState.winReason && <p className="text-lg md:text-2xl text-red-400 font-bold mb-8 text-center">{gameState.winReason}</p>}
          <button onClick={() => socket.emit('restartGame')} className="w-full max-w-xs py-3 bg-blue-700 hover:bg-blue-600 text-white rounded-xl font-bold text-lg mb-4 shadow-lg transition-colors cursor-pointer">再来一局</button>
          <button onClick={onLeave} className="w-full max-w-xs py-3 bg-gray-700 hover:bg-gray-600 text-white rounded-xl font-bold text-lg shadow-lg transition-colors cursor-pointer">返回大厅</button>
        </div>
      )}
    </div>
  );
};
