import React, { useState, useEffect, useRef, useCallback } from 'react';
import { nakamaManager } from './lib/nakama';
import './Explosion.css';
// Types for Game State (Synced with Server)
interface Player {
  userId: string;
  sessionId: string;
  username: string;
  avatar: string;
  hp: number;
  maxHp: number;
  character: string;
  // Status Flags (synced from server)
  shield: boolean;
  poisoned: boolean;
  curse: boolean;
  revive: boolean;
  timeBombTurns: number;
  skipTurn: boolean;
}

interface GridCell {
  type: 'empty' | 'bomb' | 'item';
  itemId?: string;
  revealed: boolean;
  neighborBombs?: number; // Added for classic Minesweeper logic
}

interface GameState {
  players: { [userId: string]: Player };
  grid: GridCell[];
  gridSize: number;
  turnOrder: string[];
  currentTurnIndex: number;
  round: number;
  winnerId: string | null;
  gameStarted: boolean;
}

interface LogEntry {
  id: string;
  type: 'system' | 'action' | 'effect';
  content: React.ReactNode;
}

interface FloatingLabel {
  id: string;
  x: number;
  y: number;
  text: string;
  type: 'heal' | 'damage' | 'item';
  cellIndex?: number;
  targetUserId?: string;
}

const App: React.FC = () => {
  // Game State
  const [gameState, setGameState] = useState<GameState | null>(null);
  const [logs, setLogs] = useState<LogEntry[]>([]);
  const [isConnected, setIsConnected] = useState(false);
  const [isMatching, setIsMatching] = useState(false);
  const [matchId, setMatchId] = useState<string | null>(null);
  const [myUserId, setMyUserId] = useState<string | null>(null);
  const [floatingLabels, setFloatingLabels] = useState<FloatingLabel[]>([]);
  const [showGuide, setShowGuide] = useState(false);
  const [debugMode, setDebugMode] = useState(false);
  const [matchingTimer, setMatchingTimer] = useState(0);
  const [matchPlayerCount, setMatchPlayerCount] = useState(2); // 动态匹配人数
  const [turnTimer, setTurnTimer] = useState(15); // 回合倒计时
  const [screenShaking, setScreenShaking] = useState(false); // 屏幕抖动
  const [damagedPlayers, setDamagedPlayers] = useState<string[]>([]); // 受伤玩家
  const [healedPlayers, setHealedPlayers] = useState<string[]>([]); // 治疗玩家
  const [isRefreshing, setIsRefreshing] = useState(false); // 正在刷新token

  const logsEndRef = useRef<HTMLDivElement>(null);
  const prevGameStateRef = useRef<GameState | null>(null);
  const myUserIdRef = useRef<string | null>(null);

  // Auto-scroll logs
  useEffect(() => {
    logsEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [logs]);

  // Helpers
  const addLog = useCallback((type: 'system' | 'action' | 'effect', content: React.ReactNode) => {
    setLogs(prev => [...prev.slice(-49), { id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, type, content }]);
  }, []);

  const spawnLabel = useCallback((x: number, y: number, text: string, type: 'heal' | 'damage' | 'item', cellIndex?: number, targetUserId?: string) => {
    const id = `${Date.now()}-${Math.random()}`;
    setFloatingLabels(prev => [...prev, { id, x, y, text, type, cellIndex, targetUserId }]);
    setTimeout(() => {
      setFloatingLabels(prev => prev.filter(l => l.id !== id));
    }, 1000);
  }, []);

  const describeCellContent = (cell: GridCell): string => {
    if (cell.type === 'bomb') return '💣 炸弹！';
    if (cell.type === 'item') {
      const itemNames: { [key: string]: string } = {
        'medkit': '💊 医疗包',
        'bomb_timer': '⏰ 定时炸弹',
        'poison': '☠️ 毒药',
        'shield': '🛡️ 护盾',
        'skip': '⏭️ 跳过',
        'magnifier': '🔍 放大镜',
        'knife': '🔪 匕首',
        'revive': '💖 复活',
        'lightning': '⚡ 闪电',
        'chest': '📦 宝箱',
        'curse': '👻 诅咒',
      };
      return itemNames[cell.itemId || ''] || '🎁 道具';
    }
    return '✅ 安全';
  };

  const getItemIcon = (itemId?: string): string => {
    const icons: { [key: string]: string } = {
      'medkit': '💊', 'bomb_timer': '⏰', 'poison': '☠️', 'shield': '🛡️',
      'skip': '⏭️', 'magnifier': '🔍', 'knife': '🔪', 'revive': '💖',
      'lightning': '⚡', 'chest': '📦', 'curse': '👻'
    };
    return icons[itemId || ''] || '🎁';
  };

  const renderHeart = (hp: number, maxHp: number) => {
    return (
      <div className="flex gap-0.5 flex-wrap">
        {Array.from({ length: maxHp }).map((_, i) => (
          <span key={i} className={`text-xs lg:text-sm ${i < hp ? 'text-rose-500' : 'text-slate-600'}`}>
            {i < hp ? '❤️' : '🤍'}
          </span>
        ))}
      </div>
    );
  };

  const renderStatusIcons = (player: Player) => {
    const icons: React.ReactNode[] = [];
    if (player.shield) icons.push(<span key="shield" title="护盾" className="text-blue-400">🛡️</span>);
    if (player.poisoned) icons.push(<span key="poison" title="中毒" className="text-purple-400">☠️</span>);
    if (player.curse) icons.push(<span key="curse" title="诅咒" className="text-gray-400">👻</span>);
    if (player.revive) icons.push(<span key="revive" title="复活" className="text-pink-400">💖</span>);
    if (player.timeBombTurns > 0) icons.push(<span key="bomb" title={`炸弹 ${player.timeBombTurns}回合`} className="text-red-500 animate-pulse">⏰{player.timeBombTurns}</span>);
    if (player.skipTurn) icons.push(<span key="skip" title="跳过回合" className="text-yellow-400">⏭️</span>);
    return icons.length > 0 ? <div className="flex gap-1 mt-1 text-sm">{icons}</div> : null;
  };

  const handleCellClick = (index: number) => {
    if (!gameState || !matchId || !gameState.gameStarted) return;
    const currentPlayerId = gameState.turnOrder[gameState.currentTurnIndex];
    if (currentPlayerId !== myUserIdRef.current) return;
    if (gameState.grid[index].revealed) return;
    nakamaManager.getSocket()?.sendMatchState(matchId, 3, JSON.stringify({ index }));
  };

  const startMatchmaking = async () => {
    if (matchId) {
      console.warn('Already in a match');
      return;
    }
    try {
      setIsMatching(true);
      addLog('system', `开始匹配 (${matchPlayerCount}人)...`);
      const socket = nakamaManager.getSocket();
      if (socket) {
        await socket.addMatchmaker('*', matchPlayerCount, matchPlayerCount);
        addLog('system', '正在寻找匹配...');
      }
    } catch (error) {
      console.error('Matchmaking error:', error);
      setIsMatching(false);
      const errorMsg = error instanceof Error ? error.message : '网络连接异常';
      addLog('system', `❌ 匹配失败: ${errorMsg}`);
      addLog('system', '💡 请检查网络连接后重试,或稍后再试');
    }
  };

  // 再来一局: 获取新token并重新匹配
  const refreshAndPlayAgain = async () => {
    setIsRefreshing(true);
    addLog('system', '🔄 正在获取新的游戏凭证...');

    try {
      const backendUrl = 'https://game.1024tool.vip';
      // 从小程序环境获取用户token
      let userToken = '';
      if ((window as any).uni && (window as any).uni.getStorageSync) {
        userToken = (window as any).uni.getStorageSync('token') || '';
      }

      if (!userToken) {
        addLog('system', '❌ 无法获取用户凭证,请返回小程序重新进入');
        setIsRefreshing(false);
        // 回退到小程序
        if ((window as any).uni) {
          (window as any).uni.navigateBack();
        } else if ((window as any).wx?.miniProgram) {
          (window as any).wx.miniProgram.navigateBack();
        }
        return;
      }

      const resp = await fetch(`${backendUrl}/api/app/games/enter`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${userToken}`
        },
        body: JSON.stringify({ game_code: 'minesweeper' })
      });

      if (!resp.ok) {
        const errData = await resp.json().catch(() => ({}));
        addLog('system', `❌ 获取游戏凭证失败: ${errData.message || '游戏次数不足'}`);
        setIsRefreshing(false);
        return;
      }

      const data = await resp.json();
      if (data.game_token) {
        setCurrentGameToken(data.game_token);
        addLog('system', '✅ 获取新凭证成功!');

        // 重置游戏状态
        setGameState(null);
        setMatchId(null);
        setIsMatching(false);

        // 重新初始化 Nakama 并开始匹配
        nakamaManager.initClient(data.nakama_server || 'wss://nakama.1024tool.vip', data.nakama_key || 'defaultkey');
        await nakamaManager.authenticateWithGameToken(data.game_token);
        setIsConnected(true);
        addLog('system', '✅ 重新连接成功');

        // 自动开始匹配
        setTimeout(() => startMatchmaking(), 500);
      } else {
        addLog('system', '❌ 获取游戏凭证失败');
      }
    } catch (err) {
      console.error('Refresh token error:', err);
      addLog('system', '❌ 网络错误,请稍后重试');
    }

    setIsRefreshing(false);
  };

  const GuideModal = () => (
    <div className="fixed inset-0 z-[100] flex items-center justify-center bg-black/90 backdrop-blur-md p-4 animate-in fade-in duration-300">
      <div className="bg-slate-800 border border-white/10 rounded-3xl w-full max-w-2xl max-h-[85vh] overflow-hidden flex flex-col relative shadow-2xl">
        <div className="p-6 border-b border-white/5 flex justify-between items-center bg-slate-800/50 backdrop-blur-xl">
          <h2 className="text-2xl font-black bg-gradient-to-r from-emerald-400 to-blue-400 bg-clip-text text-transparent">玩法说明 (How to Play)</h2>
          <button onClick={() => setShowGuide(false)} className="w-10 h-10 rounded-full bg-white/5 hover:bg-white/10 flex items-center justify-center transition-all">✕</button>
        </div>
        <div className="p-6 overflow-y-auto space-y-8 scrollbar-thin scrollbar-thumb-slate-700">
          <section>
            <h3 className="text-emerald-400 font-black mb-4 flex items-center gap-2"><span>🛡️</span> 道具百科</h3>
            <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
              {[
                { i: '💊', n: '医疗包', d: '回复1点HP并清除中毒状态' },
                { i: '🛡️', n: '护盾', d: '抵挡下次受到的伤害' },
                { i: '🔍', n: '放大镜', d: '随机窥视1个未翻开格子的内容' },
                { i: '🔪', n: '匕首', d: '对随机一个对手造成1点伤害' },
                { i: '⚡', n: '闪电', d: '对所有玩家（包括自己）造成1点伤害' },
                { i: '⏭️', n: '好人卡', d: '获得护盾，但跳过本回合' },
                { i: '💖', n: '复活', d: 'HP归零时立即以1HP状态复活' },
                { i: '⏰', n: '定时炸弹', d: '3回合后爆炸，对携带者造成伤害' },
                { i: '☠️', n: '毒药', d: '使随机对手中毒，每步扣除HP' },
                { i: '👻', n: '诅咒', d: '获得诅咒状态，特定操作会触发扣血' },
                { i: '📦', n: '宝箱', d: '神秘大奖，游戏结束后结算' },
              ].map(item => (
                <div key={item.n} className="bg-white/5 p-3 rounded-xl border border-white/5 flex gap-3 items-start">
                  <span className="text-2xl">{item.i}</span>
                  <div>
                    <div className="font-bold text-slate-200">{item.n}</div>
                    <div className="text-xs text-slate-400">{item.d}</div>
                  </div>
                </div>
              ))}
            </div>
          </section>
          <section>
            <h3 className="text-blue-400 font-black mb-4 flex items-center gap-2"><span>🐾</span> 角色天赋</h3>
            <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
              {[
                { i: '🐶', n: '小狗', d: '忠诚：每移动一定步数必触发放大镜效果' },
                { i: '🐘', n: '大象', d: '执拗：无法回复生命，但基础HP更高' },
                { i: '🐯', n: '虎哥', d: '猛攻：匕首进化为全屏范围伤害' },
                { i: '🐵', n: '猴子', d: '敏锐：每次点击都有概率发现香蕉(回血)' },
                { i: '🦥', n: '树懒', d: '迟缓：翻到炸弹时伤害减半(扣1点)' },
                { i: '河马', n: '河马', d: '大胃：无法直接捡起道具卡' },
              ].map(char => (
                <div key={char.n} className="bg-white/5 p-3 rounded-xl border border-white/5 flex gap-3 items-center">
                  <span className="text-2xl">{char.i}</span>
                  <div><span className="font-bold text-slate-200">{char.n}：</span><span className="text-xs text-slate-400">{char.d}</span></div>
                </div>
              ))}
            </div>
          </section>
        </div>
      </div>
    </div>
  );

  // Initialize Nakama with GameToken
  useEffect(() => {
    const initNakama = async () => {
      try {
        // Get game token from URL parameters (passed from mini-program)
        const urlParams = new URLSearchParams(window.location.search);
        const gameToken = urlParams.get('game_token');
        const nakamaServer = urlParams.get('nakama_server') || import.meta.env.VITE_NAKAMA_SERVER || 'ws://localhost:7350';
        const nakamaKey = urlParams.get('nakama_key') || import.meta.env.VITE_NAKAMA_SERVER_KEY || 'defaultkey';

        if (!gameToken) {
          addLog('system', '❌ 缺少游戏令牌');
          addLog('system', '💡 请从小程序正确入口进入游戏,或检查URL参数是否包含game_token');
          return;
        }

        // Fetch game config to get match_player_count (使用同域避免 CORS)
        try {
          const backendUrl = 'https://game.1024tool.vip'; // 通过 Nginx 反向代理到后端
          const configResp = await fetch(`${backendUrl}/api/internal/game/minesweeper/config`, {
            headers: { 'X-Internal-Key': 'bindbox-internal-secret-2024' }
          });
          if (configResp.ok) {
            const config = await configResp.json();
            if (config.match_player_count && config.match_player_count >= 2) {
              setMatchPlayerCount(config.match_player_count);
              console.log('Loaded match_player_count from config:', config.match_player_count);
            }
          }
        } catch (err) {
          console.warn('Failed to fetch game config:', err);
          addLog('system', '⚠️ 无法加载游戏配置,使用默认设置(2人匹配)');
        }

        // Initialize client with server info
        nakamaManager.initClient(nakamaServer, nakamaKey);

        // Authenticate with game token
        const session = await nakamaManager.authenticateWithGameToken(gameToken);
        const userId = session.user_id || null;
        setMyUserId(userId);
        myUserIdRef.current = userId;
        setIsConnected(true);
        addLog('system', '✅ 已连接到服务器');

        const socket = nakamaManager.getSocket();
        if (socket) {
          socket.onmatchmakermatched = async (matched) => {
            console.log('🎯 Matchmaker matched!', { matchId: matched.match_id, users: matched.users?.length });
            addLog('system', `✅ 匹配成功！找到 ${matched.users?.length || matchPlayerCount} 名玩家`);
            setIsMatching(false);
            try {
              const match = await nakamaManager.joinMatch(matched.match_id, matched.token);
              setMatchId(match.match_id);
              addLog('system', `加入房间: ${match.match_id}`);
              setTimeout(() => {
                socket.sendMatchState(match.match_id, 100, JSON.stringify({ action: 'getState' }));
              }, 100);
            } catch (error) {
              const errorMsg = error instanceof Error ? error.message : '未知错误';
              addLog('system', `❌ 加入房间失败: ${errorMsg}`);
              addLog('system', '💡 可能是网络问题或房间已满,请重新匹配');
            }
          };

          socket.onmatchdata = (matchData) => {
            const opCode = matchData.op_code;
            try {
              const data = JSON.parse(new TextDecoder().decode(matchData.data)) as GameState;
              const prevState = prevGameStateRef.current;

              if (opCode === 1) { // GAME_START
                setGameState(data);
                prevGameStateRef.current = data;
                setFloatingLabels([]); // Reset floating labels on new game
                addLog('system', '🎮 游戏开始！');
                const isMe = data.turnOrder[0] === myUserIdRef.current;
                addLog('system', isMe ? '🎯 你是先手，请点击格子！' : '⏳ 对手先手，请等待...');
              } else if (opCode === 2) { // UPDATE_STATE
                if (prevState) {
                  // Cell Reveals
                  for (let i = 0; i < data.grid.length; i++) {
                    if (data.grid[i].revealed && !prevState.grid[i].revealed) {
                      const prevPlayerId = prevState.turnOrder[prevState.currentTurnIndex];
                      const playerName = prevPlayerId === myUserIdRef.current ? '你' : (prevState.players[prevPlayerId]?.username?.substring(0, 8) || '对手');
                      const contentDesc = describeCellContent(data.grid[i]);
                      const width = data.gridSize || 10;
                      addLog('action', `${playerName} 点击了格子 [${Math.floor(i / width) + 1}, ${i % width + 1}]`);
                      addLog('effect', `发现: ${contentDesc}`);

                      // Explicit HP change labels on cells
                      let cellLabel = contentDesc.split(' ')[0];
                      let labelType: 'heal' | 'damage' | 'item' = data.grid[i].type === 'bomb' ? 'damage' : 'item';
                      if (data.grid[i].type === 'bomb') {
                        cellLabel = '-2'; // standard bomb dmg
                      } else if (data.grid[i].itemId === 'medkit') {
                        cellLabel = '+1';
                        labelType = 'heal';
                      }
                      spawnLabel(50, 50, cellLabel, labelType, i);
                    }
                  }

                  // HP Changes - 追踪伤害和治疗特效
                  Object.keys(data.players).forEach(uid => {
                    const prevHp = prevState.players[uid]?.hp || 0;
                    const newHp = data.players[uid]?.hp || 0;
                    if (newHp < prevHp) {
                      const pName = uid === myUserIdRef.current ? '你' : (data.players[uid]?.username?.substring(0, 8) || '对手');
                      addLog('effect', `💔 ${pName} 受到 ${prevHp - newHp} 点伤害！(${newHp}/${data.players[uid].maxHp})`);
                      spawnLabel(50, 20, `-${prevHp - newHp}`, 'damage', undefined, uid);
                      // 添加受伤特效
                      setDamagedPlayers(prev => [...prev, uid]);
                      setTimeout(() => setDamagedPlayers(prev => prev.filter(id => id !== uid)), 600);
                      // 如果是自己受伤,屏幕抖动
                      if (uid === myUserIdRef.current) {
                        setScreenShaking(true);
                        setTimeout(() => setScreenShaking(false), 400);
                      }
                    } else if (newHp > prevHp) {
                      const pName = uid === myUserIdRef.current ? '你' : (data.players[uid]?.username?.substring(0, 8) || '对手');
                      addLog('effect', `🌿 ${pName} 回复了 ${newHp - prevHp} 点生命！(${newHp}/${data.players[uid].maxHp})`);
                      spawnLabel(50, 20, `+${newHp - prevHp}`, 'heal', undefined, uid);
                      // 添加治疗特效
                      setHealedPlayers(prev => [...prev, uid]);
                      setTimeout(() => setHealedPlayers(prev => prev.filter(id => id !== uid)), 600);
                    }
                  });

                  // Turn Changes
                  if (data.currentTurnIndex !== prevState.currentTurnIndex) {
                    if (data.turnOrder[data.currentTurnIndex] === myUserIdRef.current) {
                      addLog('system', '🎯 轮到你了！');
                    }
                  }
                }
                setGameState(data);
                prevGameStateRef.current = data;
              } else if (opCode === 6) { // GAME_OVER
                const winnerName = data.winnerId === myUserIdRef.current ? '你' : '对手';
                addLog('system', `🏆 游戏结束！${winnerName}获胜！`);
                setGameState(prev => prev ? { ...prev, ...data, gameStarted: false } : null);
              } else if (opCode === 5) { // GAME_EVENT
                // Special event from server (character abilities, item effects)
                const event = data as unknown as { type: string; playerId: string; playerName: string; targetId?: string; targetName?: string; itemId?: string; value?: number; message: string };
                const isMe = event.playerId === myUserIdRef.current;
                const prefix = isMe ? '你' : (event.playerName?.substring(0, 8) || '对手');
                addLog('effect', `${prefix}: ${event.message}`);

                // Show floating damage/heal for affected players
                if (event.type === 'damage' || event.type === 'item') {
                  const isGlobalDamage = event.itemId === 'lightning' || (event.itemId === 'knife' && event.message.includes('所有'));

                  if (isGlobalDamage && event.value) {
                    // Global damage - show on my screen
                    spawnLabel(50, 50, `-${event.value}`, 'damage', undefined, myUserIdRef.current || undefined);
                  } else if (event.targetId === myUserIdRef.current && event.value) {
                    // I'm the target of damage
                    spawnLabel(50, 50, `-${event.value}`, 'damage', undefined, myUserIdRef.current || undefined);
                  }
                } else if (event.type === 'ability' && event.message.includes('香蕉') && event.playerId === myUserIdRef.current) {
                  // Monkey banana heal
                  spawnLabel(50, 50, '+1', 'heal', undefined, myUserIdRef.current || undefined);
                }
              }
            } catch (err) {
              console.error('Match data error:', err);
            }
          };
        }
      } catch (error) {
        addLog('system', '连接服务器失败');
      }
    };
    initNakama();
  }, [addLog, spawnLabel]);

  // 匹配计时器
  useEffect(() => {
    let timer: ReturnType<typeof setInterval>;
    if (isMatching) {
      setMatchingTimer(0);
      timer = setInterval(() => {
        setMatchingTimer(prev => prev + 1);
      }, 1000);
    }
    return () => {
      if (timer) clearInterval(timer);
      setMatchingTimer(0);
    };
  }, [isMatching]);

  // 回合倒计时器 - 与服务皂15秒同步
  useEffect(() => {
    if (!gameState?.gameStarted) return;
    // 每次回合切换时重置为15秒
    setTurnTimer(15);
    const timer = setInterval(() => {
      setTurnTimer(prev => Math.max(0, prev - 1));
    }, 1000);
    return () => clearInterval(timer);
  }, [gameState?.currentTurnIndex, gameState?.gameStarted]);

  // Render Views
  if (!isConnected) {
    return (
      <div className="min-h-screen bg-slate-900 text-white flex items-center justify-center">
        <div className="text-center">
          <div className="text-2xl mb-4">连接服务器中...</div>
          <div className="animate-spin text-4xl">⏳</div>
        </div>
      </div>
    );
  }

  if (!gameState) {
    return (
      <div className="min-h-screen bg-slate-900 text-white flex flex-col items-center justify-center p-4">
        <h1 className="text-4xl font-bold bg-gradient-to-r from-emerald-400 to-blue-500 bg-clip-text text-transparent mb-8">动物扫雷大作战</h1>
        {isMatching ? (
          <div className="bg-slate-800 p-8 rounded-2xl border border-slate-700 shadow-xl text-center space-y-4">
            <div className="text-xl font-bold text-emerald-400 animate-pulse">正在寻找对手...</div>
            <div className="text-6xl animate-spin">🌀</div>

            {/* 匹配状态信息 */}
            <div className="space-y-2 text-sm">
              <div className="flex items-center justify-center gap-2 text-slate-300">
                <span className="text-2xl">⏱️</span>
                <span className="text-lg font-mono">{matchingTimer}秒</span>
              </div>
              <div className="text-emerald-400 font-bold">
                🎮 需要 {matchPlayerCount} 名玩家
              </div>
              {matchingTimer > 3 && (
                <div className="text-yellow-400 text-xs animate-pulse mt-3">
                  ⚡ 匹配中...预计1-5秒完成
                </div>
              )}
              {matchingTimer > 8 && (
                <div className="text-orange-400 text-xs mt-2">
                  ⏳ 人数不足，继续等待中...
                </div>
              )}
            </div>
          </div>
        ) : (
          <button onClick={startMatchmaking} className="px-8 py-4 bg-emerald-600 hover:bg-emerald-500 rounded-xl font-bold text-xl transition-all active:scale-95">🚀 开始匹配 ({matchPlayerCount}人)</button>
        )}
        <div className="mt-8 w-full max-w-md bg-black/20 rounded-xl p-4 h-48 overflow-y-auto font-mono text-xs text-slate-400">
          {logs.map(log => <div key={log.id}>{log.content}</div>)}
          <div ref={logsEndRef} />
        </div>
      </div>
    );
  }

  const myPlayer = gameState.players[myUserId!] || null;
  const opponents = Object.values(gameState.players).filter(p => p.userId !== myUserId);
  const isMyTurn = gameState.turnOrder[gameState.currentTurnIndex] === myUserId;

  return (
    <div className={`min-h-screen bg-slate-900 text-white flex flex-col items-center p-2 lg:p-4 overflow-y-auto lg:overflow-hidden relative ${screenShaking ? 'screen-shake' : ''}`}>
      <div className="w-full max-w-6xl flex justify-between items-center mb-2 lg:mb-6 p-2 lg:p-4 bg-slate-800/50 backdrop-blur-md rounded-xl border border-slate-700 shrink-0">
        <div className="bg-emerald-500/20 text-emerald-400 px-3 py-1 rounded-full text-xs font-bold">Round {gameState.round}</div>
        <h1 className="text-sm lg:text-xl font-bold bg-gradient-to-r from-emerald-400 to-blue-500 bg-clip-text text-transparent">动物扫雷</h1>
        <button onClick={() => setShowGuide(true)} className="px-4 py-1.5 bg-emerald-500 hover:bg-emerald-400 text-white rounded-full text-xs font-black transition-all shadow-lg shadow-emerald-500/20 flex items-center gap-2">
          <span>📜</span> 玩法说明
        </button>
        <button onClick={() => setDebugMode(!debugMode)} className={`px-3 py-1 rounded-full text-xs font-bold transition-all ${debugMode ? 'bg-red-500 text-white' : 'bg-slate-700 text-slate-400'}`}>
          🐛 {debugMode ? '关闭明牌' : '开启明牌'}
        </button>
      </div>

      <div className="w-full max-w-6xl flex flex-col lg:grid lg:grid-cols-12 gap-2 lg:gap-6 flex-1 min-h-0">
        <div className="lg:col-span-3 flex lg:flex-col gap-2 shrink-0 overflow-x-auto lg:overflow-visible pb-2 lg:pb-0">
          {opponents.map(p => (
            <div key={p.userId} className={`bg-slate-800 p-2 lg:p-4 rounded-xl border ${gameState.turnOrder[gameState.currentTurnIndex] === p.userId ? 'border-yellow-500' : 'border-slate-700'} relative shrink-0 ${damagedPlayers.includes(p.userId) ? 'player-damaged' : ''} ${healedPlayers.includes(p.userId) ? 'player-healed' : ''}`}>
              <div className="flex items-center gap-2">
                <div className="text-2xl">{p.avatar}</div>
                <div className="relative">
                  <div className="text-xs font-bold truncate max-w-[80px]">{p.username || 'Opponent'}</div>
                  {renderHeart(p.hp, p.maxHp)}
                  {renderStatusIcons(p)}
                </div>
              </div>
            </div>
          ))}
        </div>

        <div className="lg:col-span-6 flex flex-col items-center justify-center bg-slate-800/30 rounded-2xl border border-slate-700/30 p-2 lg:p-6 relative shrink-0 lg:flex-1 min-h-0">
          {/* 回合指示器和倒计时 */}
          <div className="flex items-center gap-3 mb-2">
            <div className={`px-4 py-1 rounded-full text-xs lg:text-sm font-bold ${isMyTurn ? 'bg-emerald-500 text-white' : 'bg-slate-700 text-slate-400'}`}>
              {isMyTurn ? '🎯 你的回合' : '⏳ 等待对手'}
            </div>
            <div className={`flex items-center gap-1 px-3 py-1 rounded-full ${turnTimer <= 5 ? 'bg-red-500/30 timer-urgent' : 'bg-slate-700/50'}`}>
              <span className="text-lg">⏱️</span>
              <span className={`text-lg font-mono font-bold ${turnTimer <= 5 ? 'text-red-400' : 'text-yellow-400'}`}>{turnTimer}</span>
              <span className="text-xs text-slate-400">秒</span>
            </div>
          </div>
          {/* 倒计时进度条 */}
          <div className="w-full max-w-[200px] h-1 bg-slate-700 rounded-full mb-3 overflow-hidden">
            <div
              className={`h-full rounded-full transition-all duration-1000 ${turnTimer <= 5 ? 'bg-red-500' : turnTimer <= 10 ? 'bg-yellow-500' : 'bg-emerald-500'}`}
              style={{ width: `${(turnTimer / 15) * 100}%` }}
            />
          </div>
          <div className="grid gap-0.5 lg:gap-1 w-full max-w-[500px] aspect-square" style={{ gridTemplateColumns: `repeat(${gameState.gridSize || 10}, 1fr)` }}>
            {gameState.grid.map((cell, idx) => {
              const showContent = cell.revealed || debugMode;
              return (
                <div key={idx} onClick={() => handleCellClick(idx)} className={`aspect-square rounded-sm relative flex items-center justify-center text-sm lg:text-2xl border border-white/5 transition-all
                  ${showContent ? (cell.type === 'bomb' ? 'bg-rose-900/50' + (cell.revealed ? ' explosion' : '') : cell.type === 'item' ? `bg-blue-900/40${cell.revealed ? ` item-${cell.itemId || 'generic'}` : ''}` : 'bg-slate-800/50') : 'bg-emerald-900/20 hover:bg-emerald-800/40 cursor-pointer'}
                  ${debugMode && !cell.revealed ? 'opacity-60 border-dashed border-yellow-500/50' : ''}`}>
                  {showContent && (
                    cell.type === 'bomb' ? '💣' :
                      cell.type === 'item' ? getItemIcon(cell.itemId) :
                        (cell.neighborBombs ? (
                          <span style={{
                            color: [
                              '', '#3b82f6', '#22c55e', '#ef4444', '#a855f7', '#f97316', '#06b6d4', '#ec4899', '#64748b'
                            ][cell.neighborBombs] || 'white',
                            fontWeight: '900',
                            textShadow: '0 0 5px rgba(0,0,0,0.5)'
                          }}>
                            {cell.neighborBombs}
                          </span>
                        ) : (debugMode ? '✅' : ''))
                  )}
                  {floatingLabels.filter(l => l.cellIndex === idx).map(l => (
                    <div key={l.id} className="float-label" style={{ color: l.type === 'heal' ? '#10b981' : l.type === 'damage' ? '#ef4444' : '#fbbf24', top: '50%', left: '50%', transform: 'translate(-50%, -50%)' }}>{l.text}</div>
                  ))}
                </div>
              );
            })}
          </div>
        </div>

        <div className="lg:col-span-3 flex flex-col gap-2 lg:gap-4 shrink-0 lg:overflow-hidden">
          {myPlayer && (
            <div className={`bg-slate-800 p-4 rounded-2xl border ${isMyTurn ? 'border-emerald-500' : 'border-slate-700'} relative ${damagedPlayers.includes(myPlayer.userId) ? 'player-damaged' : ''} ${healedPlayers.includes(myPlayer.userId) ? 'player-healed' : ''}`}>
              <div className="flex items-center gap-4">
                <div className="text-4xl">{myPlayer.avatar}</div>
                <div className="relative">
                  <div className="font-bold text-lg">我</div>
                  {renderHeart(myPlayer.hp, myPlayer.maxHp)}
                  {renderStatusIcons(myPlayer)}
                </div>
              </div>
            </div>
          )}
          <div className="h-32 lg:flex-1 bg-black/20 rounded-xl p-4 overflow-hidden flex flex-col">
            <h3 className="text-slate-500 text-xs font-bold uppercase mb-2">战斗日志</h3>
            <div className="flex-1 overflow-y-auto text-xs space-y-1">
              {logs.map(log => <div key={log.id} className={log.type === 'system' ? 'text-yellow-400' : log.type === 'action' ? 'text-blue-300' : 'text-emerald-400'}>{log.content}</div>)}
              <div ref={logsEndRef} />
            </div>
          </div>
        </div>
      </div>

      {!gameState.gameStarted && gameState.winnerId && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-sm">
          <div className="bg-slate-800 p-8 rounded-3xl text-center max-w-sm w-full">
            <div className="text-6xl mb-4">{gameState.winnerId === myUserId ? '🏆' : '💀'}</div>
            <h2 className="text-3xl font-bold mb-4">{gameState.winnerId === myUserId ? '胜利！' : '失败'}</h2>
            <button
              onClick={refreshAndPlayAgain}
              disabled={isRefreshing}
              className="w-full bg-emerald-600 hover:bg-emerald-500 disabled:bg-slate-600 text-white font-bold py-3 rounded-xl transition-all"
            >
              {isRefreshing ? '🔄 正在准备...' : '🚀 再来一局'}
            </button>
            <button
              onClick={() => {
                if ((window as any).uni) {
                  (window as any).uni.navigateBack();
                } else if ((window as any).wx?.miniProgram) {
                  (window as any).wx.miniProgram.navigateBack();
                } else {
                  window.location.href = 'about:blank';
                }
              }}
              className="w-full mt-2 bg-slate-700 hover:bg-slate-600 text-white font-bold py-2 rounded-xl text-sm"
            >
              返回
            </button>
          </div>
        </div>
      )}

      {showGuide && <GuideModal />}
    </div>
  );
};

export default App;
