const { useState, useEffect, useRef } = React;

// 动态计算轨迹的敬酒杯组件
const DynamicFlyingCup = ({ sourceId, targetId, sourceName, targetName }) => {
    const [styleInfo, setStyleInfo] = useState(null);

    useEffect(() => {
        const sourceEl = document.getElementById(`player-name-${sourceId}`);
        const targetEl = document.getElementById(`player-name-${targetId}`);
        
        if (sourceEl && targetEl) {
            const sRect = sourceEl.getBoundingClientRect();
            const tRect = targetEl.getBoundingClientRect();
            const animName = `fly_${Date.now()}_${Math.floor(Math.random()*1000)}`;
            
            setStyleInfo({
                animName,
                startX: sRect.left + sRect.width / 2,
                startY: sRect.top + sRect.height / 2,
                endX: tRect.left + tRect.width / 2,
                endY: tRect.top + tRect.height / 2,
            });
        } else {
            // 后备居中动画
            const animName = `fly_${Date.now()}_${Math.floor(Math.random()*1000)}`;
            setStyleInfo({
                animName, startX: window.innerWidth / 2, startY: window.innerHeight / 2,
                endX: window.innerWidth / 2, endY: window.innerHeight / 2
            });
        }
    }, [sourceId, targetId]);

    if (!styleInfo) return null;

    return (
        <div className="fixed z-[9999] pointer-events-none" style={{ left: 0, top: 0, animation: `${styleInfo.animName} 1.5s cubic-bezier(0.25, 1, 0.5, 1) forwards` }}>
            <style>{`
                @keyframes ${styleInfo.animName} {
                    0% { transform: translate(${styleInfo.startX}px, ${styleInfo.startY}px) scale(0.3) rotate(-15deg); opacity: 0; }
                    20% { transform: translate(${styleInfo.startX}px, ${styleInfo.startY}px) scale(1.2) rotate(0deg); opacity: 1; }
                    80% { transform: translate(${styleInfo.endX}px, ${styleInfo.endY}px) scale(1.2) rotate(0deg); opacity: 1; }
                    100% { transform: translate(${styleInfo.endX}px, ${styleInfo.endY}px) scale(0.3) rotate(15deg); opacity: 0; }
                }
            `}</style>
            <div className="transform -translate-x-1/2 -translate-y-1/2 flex flex-col items-center">
                <span className="text-xs md:text-sm font-bold text-cyan-300 drop-shadow-md bg-black/60 px-2 py-0.5 rounded-full whitespace-nowrap mb-1 border border-cyan-500/30">
                    {sourceName} 敬酒给 {targetName}
                </span>
                <div className="text-5xl md:text-6xl drop-shadow-[0_0_15px_rgba(255,0,0,0.8)]">🍷</div>
            </div>
        </div>
    );
};


window.Game5_8P = function Game5_8P({ 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 text-lg">正在布置混战圆桌...</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 maxCupLimit = 5; 
  const isForcedToDrink = gameState.cupModifiers?.force || gameState.cupStack?.length >= maxCupLimit;
  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 >= 3;
      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); 
     
     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-5xl md: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-6xl">🌀</span></div>)}
        </div>
    );
  };

  // === 5-8人 环绕布局计算 ===
  const numOpp = opponents.length;
  let topCount = 0, leftCount = 0, rightCount = 0;
  if (numOpp <= 3) { topCount = numOpp; }
  else if (numOpp === 4) { topCount = 2; leftCount = 1; rightCount = 1; }
  else if (numOpp === 5) { topCount = 3; leftCount = 1; rightCount = 1; }
  else if (numOpp === 6) { topCount = 2; leftCount = 2; rightCount = 2; }
  else if (numOpp === 7) { topCount = 3; leftCount = 2; rightCount = 2; }
  
  const topOpponents = opponents.slice(0, topCount);
  const leftOpponents = opponents.slice(topCount, topCount + leftCount);
  const rightOpponents = opponents.slice(topCount + leftCount);

  // 对手盒子渲染 (自适应手机和小屏幕，整体放大)
  const renderOpponentBox = (opp) => {
      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={`bg-gray-800 p-2 md:p-3 rounded-xl border-2 transition-all relative overflow-hidden w-full max-w-[130px] sm:max-w-[160px] md:max-w-[220px] mx-auto shrink-0
             ${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 flex items-center justify-center backdrop-blur-[2px]">
                    <div className="transform -rotate-12 border-2 border-red-600 px-1.5 py-0.5 md:px-2 md:py-1 rounded-lg text-red-600 font-black text-sm md:text-xl tracking-widest bg-black bg-opacity-80 shadow-[0_0_10px_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-sm mb-1 truncate text-center">{opp.name} {opp.isAI && '🤖'} {opp.tipsyStatus && <span className="text-pink-400 font-bold ml-0.5">🌀</span>}</h3>
            
            <div className="flex flex-col xl:flex-row gap-0.5 xl:gap-1 text-[10px] md:text-xs mb-1.5 justify-between px-0.5 md:px-1">
               <span className="text-red-400 font-bold text-center xl:text-left">❤️ {opp.hp}</span>
               <span className="text-yellow-400 font-bold text-center xl:text-right">🏆 {opp.score}/6</span>
            </div>
            
            <div className="flex items-center gap-1 mt-1 bg-gray-900 p-1 md:p-1.5 rounded-md md:rounded-lg justify-center border border-gray-700">
               <div className="w-4 h-5 md:w-5 md:h-7 card-back rounded border border-gray-500 shadow-sm flex items-center justify-center"><span className="text-[8px] md:text-[10px] text-gray-400">🂠</span></div>
               <span className="text-gray-300 text-[10px] md:text-xs font-bold">× {opp.hand.length}</span>
            </div>
         </div>
      );
  };

  return (
    <div className={`h-screen 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-95 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="fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-[150] pointer-events-none flex flex-col items-center justify-center bg-black/85 px-5 py-4 rounded-3xl border border-yellow-500/50 backdrop-blur-md shadow-2xl">
             <h2 className="text-sm md:text-xl text-yellow-400 font-bold animate-pulse drop-shadow-lg text-center mb-3 pointer-events-auto">👉 请点击想针对的对手头像</h2>
             <button onClick={() => setTargeting({active: false})} className="px-5 py-2 bg-gray-700 rounded-full text-white text-xs md:text-sm font-bold cursor-pointer hover:bg-gray-500 shadow-lg pointer-events-auto border border-gray-500 transition-colors">取消选择</button>
          </div>
       )}

       {/* 顶部状态栏 */}
       <div className="flex justify-between items-center text-sm text-gray-400 bg-gray-900 p-2 z-50 shrink-0 border-b border-gray-800">
          <span>🔖 房间: {gameState.roomId} (5-8人)</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-1.5 shrink-0">
          <div className="text-xs sm:text-sm font-bold text-red-400 drop-shadow-lg bg-gray-900 px-5 py-1.5 rounded-full shadow-xl border border-gray-800">
              {getPhaseStatusText()}
          </div>
       </div>

       {/* 主布局 */}
       <div className="flex-1 relative flex min-h-0 px-1 sm:px-2 w-full max-w-7xl mx-auto">
           <div className="flex-1 flex flex-col overflow-x-hidden overflow-y-auto custom-scrollbar relative pt-1 md:pt-2 pb-2 md:pb-4 w-full">
               
               {/* 顶部对手 */}
               {topOpponents.length > 0 && (
                   <div className="flex justify-center gap-2 md:gap-4 w-full shrink-0 z-10 px-1 mt-1">
                       {topOpponents.map(renderOpponentBox)}
                   </div>
               )}

               {/* 中间层 (左侧对手 + 中央酒桌 + 右侧对手) */}
               <div className="flex-1 flex flex-row items-center justify-between w-full my-2 min-h-0 z-0">
                   
                   {/* 左侧对手 */}
                   <div className="flex flex-col gap-4 md:gap-6 justify-evenly h-full w-[28%] md:w-[22%] z-10 shrink-0 py-2 md:py-6">
                       {leftOpponents.map(renderOpponentBox)}
                   </div>

                   {/* 中央酒桌 (放大) */}
                   <div className="flex-1 flex flex-col items-center justify-center relative shrink-0 px-1">
                       <div className="relative w-44 h-44 sm:w-56 sm:h-56 md:w-72 md:h-72 bg-red-900 bg-opacity-20 rounded-full border-2 md:border-4 border-red-900 flex flex-col items-center justify-center p-3 md:p-4 shadow-xl">
                          {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-1.5 md:gap-3">
                                {gameState.cupStack.map((c, i) => (
                                    <div key={i} className={`relative overflow-hidden w-11 h-16 sm:w-14 sm:h-20 md:w-16 md:h-24 rounded-md md:rounded-lg ${window.getCardStyle(c)} shadow-md ${c.faceUp && c.drank === false ? 'opacity-40 grayscale' : ''}`}>
                                        {c.faceUp ? (
                                          <>
                                            <div className="absolute inset-0 flex items-center justify-center pb-2 md:pb-3">
                                               <span className="text-xl md:text-3xl">{window.getCardIcon(c)}</span>
                                            </div>
                                            <div className="absolute bottom-0 w-full bg-black py-[1px] md:py-0.5 flex 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-[1px] md:py-0.5 flex justify-center">
                                               <span className="text-[9px] md:text-[10px] text-gray-400 truncate px-0.5">{c.ownerName}</span>
                                            </div>
                                        )}
                                    </div>
                                ))}
                            </div>
                          }
                       </div>
                   </div>

                   {/* 右侧对手 */}
                   <div className="flex flex-col gap-4 md:gap-6 justify-evenly h-full w-[28%] md:w-[22%] z-10 shrink-0 py-2 md:py-6">
                       {rightOpponents.map(renderOpponentBox)}
                   </div>
               </div>

               {/* 底部 自己区域 (放大) */}
                <div className="w-full flex justify-center shrink-0 mt-auto z-20 pt-1 pb-[calc(7rem+env(safe-area-inset-bottom))]">
                   <div className={`bg-gray-800 p-2.5 md:p-4 rounded-xl border-2 w-full max-w-[800px] transition-all relative ${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-2 md:border-4 border-red-600 px-4 py-2 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 md:mb-2">
                           <h3 id={`player-name-${me.id}`} className="font-bold text-yellow-400 text-sm md:text-lg truncate mr-2">{me.name} (你) {me.tipsyStatus && <span className="text-pink-400 ml-1">🌀微醺</span>}</h3>
                           <div className="flex gap-2 text-[11px] md:text-sm">
                               <span className="text-red-400 font-bold bg-gray-900 px-2 py-0.5 rounded-full">❤️ {me.hp}</span>
                               <span className="text-yellow-400 font-bold bg-gray-900 px-2 py-0.5 rounded-full">🏆 {me.score}/6</span>
                           </div>
                       </div>
                        
                        {/* 玩家自己的手牌直接铺开展示 (卡牌放大) */}
                        <div className="flex gap-2 md:gap-3 justify-center mb-1.5 flex-wrap min-h-[80px] md:min-h-[100px]">
                          {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-14 h-20 sm:w-16 sm:h-24 md:w-16 md:h-24 rounded-md md:rounded-lg cursor-pointer shadow-lg block ${window.getCardStyle(c)} ${(me.hp <= 0 || !playable) ? 'disabled' : ''} ${isSelected ? 'selected ring-2 ring-yellow-400' : ''}`}>
                                  <div className="absolute inset-0 flex items-center justify-center pb-2 md:pb-3">
                                      <span className="text-2xl md:text-3xl">{window.getCardIcon(c)}</span>
                                  </div>
                                  <div className="absolute bottom-0 w-full bg-black py-[2px] md:py-0.5 flex justify-center">
                                      <span className="text-[9px] sm:text-[11px] 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-3 md:gap-4 justify-center mt-2">
                              <button onClick={handleDrinkClick} className="px-4 md:px-6 py-1.5 md:py-1.5 bg-red-700 hover:bg-red-600 text-white font-bold rounded-lg shadow-lg text-xs md:text-sm transition-colors">一饮而下！</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-6 py-1.5 md:py-1.5 rounded-lg font-bold shadow-lg text-xs md:text-sm transition-colors ${!isForcedToDrink && selectedNormalId ? 'bg-blue-700 hover:bg-blue-600 text-white' : 'bg-gray-700 text-gray-500'}`}>添酒推杯</button>
                          </div>
                       )}
                   </div>
               </div>
           </div>

           {/* 桌面端才显示的右侧日志 */}
           <div className="hidden lg:flex w-72 bg-gray-900 border-l border-gray-700 flex-col overflow-hidden shrink-0 shadow-lg relative z-[110]">
              <div className="p-3 bg-gray-800 flex justify-between items-center border-b border-gray-700 shadow-md">
                  <span className="font-bold text-yellow-500 text-sm">📜 日志</span>
              </div>
              <div className="flex-1 p-3 overflow-y-auto space-y-2.5 text-sm text-gray-300 custom-scrollbar">
                {logs.map(log => <div key={log.id} className="border-b border-gray-800 pb-1.5"><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 <DynamicFlyingCup 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-2 md:border-4 border-yellow-400 p-5 md:p-6 rounded-2xl md:rounded-3xl flex flex-col items-center shadow-[0_0_40px_rgba(250,204,21,0.8)] min-w-[200px] md:min-w-[240px] shrink-0">
                        <span className="text-5xl md:text-6xl mb-2">🌟</span>
                        <h2 className="text-xl md:text-2xl text-white font-bold mb-2">全场狂欢赞赏</h2>
                        <h2 className="text-2xl md:text-3xl text-yellow-400 font-black tracking-widest" style={{ textShadow: '0 2px 8px 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_30px_rgba(234,179,8,0.5)] min-w-[160px] 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-lg md: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-[2px] md:py-1 flex items-center justify-center">
                               <span className="text-[10px] md:text-sm font-bold text-white truncate px-1">{a.card.name}</span>
                            </div>
                        </div>
                        {targetName && <h2 className="text-sm 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_30px_rgba(0,0,0,0.8)] grayscale min-w-[160px] 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-lg md: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-[2px] md:py-1 flex items-center justify-center">
                               <span className="text-[10px] md:text-sm font-bold text-white truncate px-1">{a.card.name}</span>
                            </div>
                        </div>
                        <h2 className="text-xs 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-2 md:border-4 border-red-500 p-4 md:p-6 rounded-2xl md:rounded-3xl flex flex-col items-center shadow-[0_0_50px_rgba(220,38,38,0.8)] min-w-[160px] md:min-w-[240px] shrink-0">
                        <h2 className="text-base md:text-2xl text-white font-bold mb-2"><span className="text-cyan-400 font-black">{sourceName}</span> 端起 {a.count} 杯酒</h2>
                        <div className="w-16 h-16 md:w-32 md:h-32 my-2 sprite-drink rounded-xl md:rounded-2xl shadow-inner border border-red-500/20 bg-black/30"></div>
                        <h2 className="text-xl md:text-4xl text-yellow-400 font-black tracking-widest" style={{ textShadow: '0 2px 8px 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 && gameState.cupStack.length >= 3; if(!canSkill) skillReason = "酒桌上少于3杯酒"; }
            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-6 rounded-2xl border border-yellow-600 max-w-[320px] md:max-w-sm w-full text-center shadow-2xl modal-pop">
              <h3 className="text-xl text-yellow-500 font-bold mb-3">抉择时刻</h3>
              <p className="text-gray-300 mb-5 text-sm">如何使用【{c.name}】？</p>
              <div className="flex gap-3 flex-col">
                <div className="relative w-full">
                    <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-3 rounded-lg 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-400 cursor-not-allowed border border-gray-600'}`}>
                      {canSkill ? '🗡️ 发动技能' : `⛔ 无法发动 (${skillReason})`}
                    </button>
                </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-3 rounded-lg 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.5 mt-2 bg-gray-600 hover:bg-gray-500 text-white font-bold text-sm rounded-lg transition-colors">取消</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-6 rounded-2xl border border-red-600 max-w-[340px] md:max-w-sm w-full text-center shadow-2xl modal-pop">
            <h3 className="text-xl text-red-500 font-bold mb-3">🍷 饮酒抉择</h3>
            <p className="text-sm text-gray-300 mb-4">请选择你要喝下的牌（至少选择1杯）：</p>
            <div className="flex gap-3 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">
                            <span className="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] font-bold text-white truncate px-1">{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] font-bold text-gray-400 truncate px-1">{c.ownerName}</span>
                       </div>
                    )}
                  </div>
                );
              })}
            </div>
            <div className="flex gap-4">
              <button onClick={() => setDrinkModal({open:false, selectedIds:[]})} className="flex-1 py-2.5 bg-gray-600 hover:bg-gray-500 text-white rounded-lg font-bold text-sm transition-colors">再想想</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-lg font-bold text-white text-sm transition-colors ${drinkModal.selectedIds.length > 0 ? 'bg-red-600 hover:bg-red-500' : '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-6 rounded-2xl border border-yellow-600 max-w-[340px] md:max-w-sm w-full shadow-2xl modal-pop">
            <h3 className="text-xl text-yellow-500 font-bold text-center mb-4">🎭 偷天换日</h3>
            <p className="text-sm text-gray-300 mb-2 font-bold">1. 选桌上的牌：</p>
            <div className="flex gap-3 mb-4 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-14 h-20 md:w-20 md:h-28 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">
                          <span className="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-[10px] font-bold text-white truncate px-1">{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-1">{c.ownerName}</span>
                     </div>
                  )}
                </div>
              ))}
            </div>
            <p className="text-sm text-gray-300 mb-2 font-bold">2. 选自己的牌：</p>
            <div className="flex gap-3 mb-5 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-14 h-20 md:w-20 md:h-28 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">
                     <span className="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-[10px] font-bold text-white truncate px-1">{c.name}</span>
                  </div>
                </div>
              ))}
            </div>
            <div className="flex gap-4">
              <button onClick={() => setSwapModal({open:false})} className="flex-1 py-2.5 bg-gray-600 hover:bg-gray-500 text-white rounded-lg font-bold text-sm transition-colors">取消</button>
              <button onClick={() => { socket.emit('playItemCard', { cardId: swapModal.itemId, targetData: { targetHandCardId: swapModal.myCardId, targetCupCardId: swapModal.cupCardId } }); setSwapModal({open:false}); }} disabled={!swapModal.myCardId || !swapModal.cupCardId} className={`flex-1 py-2.5 rounded-lg font-bold text-sm transition-colors ${!swapModal.myCardId || !swapModal.cupCardId ? 'bg-gray-700 text-gray-400 cursor-not-allowed' : 'bg-yellow-600 hover:bg-yellow-500 text-black'}`}>
                  {(!swapModal.myCardId || !swapModal.cupCardId) ? '请选择两张牌' : '确认偷换'}
              </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-6 rounded-2xl border border-blue-500 max-w-[340px] md:max-w-sm w-full text-center shadow-2xl modal-pop">
            <h3 className="text-xl text-blue-400 font-bold mb-4">🪡 银针试毒</h3>
            <div className="flex gap-3 justify-center flex-wrap mb-6 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-lg md:rounded-xl block border-2 ${window.getCardStyle({...c, faceUp: true})}`}>
                  <div className="absolute inset-0 flex items-center justify-center pb-3">
                     <span className="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] font-bold text-white truncate px-1">{c.name}</span>
                  </div>
                </div>
              ))}
            </div>
            <button onClick={() => setPeekModal({open:false, result: null})} className="w-full py-3 bg-blue-600 hover:bg-blue-500 text-white rounded-xl font-bold text-sm transition-colors">了然于胸</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-6 rounded-2xl border border-purple-500 max-w-[340px] md:max-w-sm w-full text-center shadow-2xl modal-pop">
            <h3 className="text-xl text-purple-400 font-bold mb-3">🍶 同甘共苦</h3>
            <p className="text-sm text-gray-300 mb-4">选择【你】要喝下的酒（留至少1杯）：</p>
            <div className="flex gap-3 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-2 md: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">
                            <span className="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] font-bold text-white truncate px-1">{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] font-bold text-gray-400 truncate px-1">{c.ownerName}</span>
                       </div>
                    )}
                  </div>
                );
              })}
            </div>
            <div className="flex 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-lg font-bold text-sm transition-colors">取消</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-lg 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' : 'bg-gray-700 opacity-80 cursor-not-allowed'}`}>
                  {(shareModal.mySelectedIds.length === 0) ? '请选择牌' : (shareModal.mySelectedIds.length >= gameState.cupStack.length ? '必须留1杯' : '确认分配')}
              </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-6 rounded-2xl border border-gray-400 max-w-[340px] md:max-w-sm w-full text-center shadow-2xl modal-pop">
            <h3 className="text-xl text-gray-300 font-bold mb-3">🔨 碎盏</h3>
            <p className="text-sm text-gray-300 mb-4">请选择你要敲碎的酒：</p>
            <div className="flex gap-3 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">
                          <span className="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] font-bold text-white truncate px-1">{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] font-bold text-gray-400 truncate px-1">{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-lg 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">再来一局</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">返回大厅</button>
        </div>
      )}
    </div>
  );
};