<template>
  <view class="container" :class="{ 'screen-shake': screenShaking }">
    <!-- 背景 -->
    <view class="bg-dark-grid"></view>

    <!-- 连接中状态 -->
    <view v-if="!isConnected" class="loading-screen">
      <view class="loading-content">
        <view class="loading-spinner">📡</view>
        <text class="loading-text">正在寻找基站...</text>
      </view>
    </view>

    <!-- 匹配大厅 -->
    <view v-else-if="!gameState" class="lobby-screen">
      <view class="bg-decoration"></view>
      
      <view class="lobby-content fadeInUp">
        <text class="game-title">动物扫雷大作战</text>
        
        <view v-if="isMatching" class="match-box glass-card">
          <view class="scanner-box pulse">
            <view class="scanner-line"></view>
            <text class="match-spinner">🦁</text>
          </view>
          <text class="match-status">正在匹配全球玩家...</text>
          
          <view class="match-info">
            <view class="timer-row">
              <text class="timer-label">等待时长</text>
              <text class="timer-value">{{ matchingTimer }}s</text>
            </view>
            
            <view class="status-tip">
              <text v-if="matchingTimer <= 30" class="tip-normal">⚡ 正在接入星际网道</text>
              <text v-else-if="matchingTimer <= 60" class="tip-warning">⏳ 搜索频率增强中...</text>
              <text v-else class="tip-error">⚠️ 信号微弱，请重试</text>
            </view>
            
            <view class="btn-secondary cancel-btn" @tap="cancelMatchmaking">
              取消匹配
            </view>
          </view>
        </view>

        <view v-else class="start-box">
          <view class="game-intro-card glass-card">
            <view class="intro-item">
              <text class="intro-icon">🎮</text>
              <text class="intro-text">{{ matchPlayerCount }}人经典竞技模式</text>
            </view>
            <view class="intro-item">
              <text class="intro-icon">🏆</text>
              <text class="intro-text">胜者赢取全额奖励</text>
            </view>
          </view>
          
          <view class="btn-primary start-btn" @tap="startMatchmaking">
            <text class="btn-text">🚀 开始匹配</text>
          </view>
        </view>

        <!-- 游戏日志 -->
        <view class="log-section glass-card">
          <view class="log-header">
            <text class="log-title">通讯终端 (LIVE)</text>
            <view class="online-indicator"></view>
          </view>
          <scroll-view scroll-y class="mini-logs" :scroll-top="logsScrollTop">
            <view v-for="log in logs" :key="log.id" class="log-item" :class="'log-' + log.type">
              <text class="log-time">[{{ log.time }}]</text>
              <text class="log-content">{{ log.content }}</text>
            </view>
            <view v-if="logs.length === 0" class="log-empty">等待操作指令...</view>
          </scroll-view>
        </view>
      </view>
    </view>

    <!-- 游戏主界面 -->
    <view v-else class="game-screen">
      <!-- 顶部状态栏 -->
      <view class="game-header">
        <view class="round-badge">Round {{ gameState.round }}</view>
        <text class="header-title">动物扫雷</text>
        <view class="header-actions">
          <view class="btn-icon" @tap="showGuide = true">📜</view>
          <view class="btn-icon" :class="{ active: debugMode }" @tap="debugMode = !debugMode">🐛</view>
        </view>
      </view>

      <view class="game-layout">
        <!-- 对手列表 (横向滚动) -->
        <scroll-view scroll-x class="opponents-bar">
          <view class="opponents-list">
            <view 
              v-for="p in opponents" 
              :key="p.userId" 
              class="player-card opponent"
              :class="{ 
                'active-turn': gameState.turnOrder[gameState.currentTurnIndex] === p.userId,
                'damaged': damagedPlayers.includes(p.userId),
                'healed': healedPlayers.includes(p.userId)
              }"
            >
              <text class="avatar">{{ getPlayerAvatar(p) }}</text>
              <view class="player-info">
                <text class="username">{{ p.username || '对手' }}</text>
                <view class="hp-bar">
                  <text 
                    v-for="(n, i) in p.maxHp" 
                    :key="i" 
                    class="heart"
                    :class="{ filled: i < p.hp }"
                  >{{ i < p.hp ? '❤️' : '🤍' }}</text>
                </view>
                <view class="status-icons">
                  <text v-if="p.shield" class="icon">🛡️</text>
                  <text v-if="p.poisoned" class="icon">☠️</text>
                  <text v-if="p.curse" class="icon">👻</text>
                  <text v-if="p.revive" class="icon">💖</text>
                  <text v-if="p.timeBombTurns > 0" class="icon pulse">⏰{{p.timeBombTurns}}</text>
                  <text v-if="p.skipTurn" class="icon">⏭️</text>
                </view>
              </view>
              
              <!-- 玩家身上的飘字 -->
              <view v-for="l in getPlayerLabels(p.userId)" :key="l.id" class="float-label" :class="'text-' + l.type" style="top: 20%; left: 50%; transform: translateX(-50%);">
                {{ l.text }}
              </view>
            </view>
          </view>
        </scroll-view>

        <!-- 棋盘区 -->
        <view class="board-area">
          <view class="turn-indicator" v-if="gameState.gameStarted">
            <view class="turn-badge" :class="{ 'my-turn pulse': isMyTurn }">
              {{ isMyTurn ? '您的回合' : '等待对手...' }}
            </view>
            <view class="timer-badge" :class="{ urgent: turnTimer < 5 }">
              ⏱️ {{ turnTimer }}s
            </view>
          </view>

          <view class="timer-progress-bg" v-if="gameState.gameStarted">
            <view 
              class="timer-progress-fill" 
              :style="{ width: (turnTimer / 15 * 100) + '%' }"
              :class="turnTimer < 5 ? 'bg-red' : (turnTimer < 10 ? 'bg-yellow' : 'bg-green')"
            ></view>
          </view>

          <view class="grid-board" :style="{ gridTemplateColumns: 'repeat(' + gameState.gridSize + ', 1fr)' }">
            <view 
              v-for="(cell, i) in gameState.grid" 
              :key="i" 
              class="grid-cell"
              :class="[
                cell.revealed ? (cell.type === 'bomb' ? 'type-bomb explosion' : (cell.type === 'item' ? 'type-item item-' + (cell.itemId || 'generic') : 'type-empty')) : 'bg-slate-800',
                { 
                  'revealed': cell.revealed, 
                  'has-magnifier': myPlayer && myPlayer.revealedCells && myPlayer.revealedCells[i]
                }
              ]"
              @tap="handleCellClick(i)"
            >
              <view v-if="cell.revealed">
                <text v-if="cell.type === 'bomb'" class="cell-icon">💣</text>
                <text v-else-if="cell.type === 'empty'" class="cell-num" :style="{ color: getNumColor(cell.neighborBombs) }">
                  {{ cell.neighborBombs > 0 ? cell.neighborBombs : '' }}
                </text>
                <text v-else-if="cell.type === 'item'" class="cell-icon">{{ getItemIcon(cell.itemId) }}</text>
              </view>
              <view v-else-if="myPlayer && myPlayer.revealedCells && myPlayer.revealedCells[i]" class="magnifier-mark">
                 <text class="cell-icon magnifier-content">{{ getContentIcon(myPlayer.revealedCells[i]) }}</text>
                 <text class="magnifier-badge">🔍</text>
              </view>

              <!-- 格子上的飘字 -->
              <view v-for="l in getCellLabels(i)" :key="l.id" class="float-label" :class="'text-' + l.type">
                {{ l.text }}
              </view>
            </view>
          </view>
        </view>

        <!-- 底部面板 -->
        <view class="bottom-panel">
          <view v-if="myPlayer" class="player-card me" 
            :class="{ 
              'active-turn': isMyTurn,
              'damaged': damagedPlayers.includes(myPlayer.userId),
              'healed': healedPlayers.includes(myPlayer.userId)
            }"
          >
            <text class="avatar lg">{{ getPlayerAvatar(myPlayer) }}</text>
            <view class="player-info">
              <text class="username font-bold">我</text>
              <view class="hp-bar">
                <text 
                  v-for="(n, i) in myPlayer.maxHp" 
                  :key="i" 
                  class="heart"
                  :class="{ filled: i < myPlayer.hp }"
                >{{ i < myPlayer.hp ? '❤️' : '🤍' }}</text>
              </view>
              <view class="status-icons">
                <text v-if="myPlayer.shield" class="icon">🛡️</text>
                <text v-if="myPlayer.poisoned" class="icon">☠️</text>
                <text v-if="myPlayer.curse" class="icon">👻</text>
                <text v-if="myPlayer.revive" class="icon">💖</text>
                <text v-if="myPlayer.timeBombTurns > 0" class="icon pulse">⏰{{myPlayer.timeBombTurns}}</text>
                <text v-if="myPlayer.skipTurn" class="icon">⏭️</text>
              </view>
            </view>
            
            <!-- 我身上的飘字 -->
            <view v-for="l in getPlayerLabels(myPlayer.userId)" :key="l.id" class="float-label" :class="'text-' + l.type" style="top: -20rpx; left: 50%; transform: translateX(-50%);">
              {{ l.text }}
            </view>
          </view>

          <!-- 迷你日志栏 -->
          <scroll-view scroll-y class="game-logs" :scroll-top="logsScrollTop">
            <view v-for="log in logs" :key="log.id" class="log-line" :class="'log-' + log.type">
              {{ log.content }}
            </view>
          </scroll-view>
        </view>
      </view>
    </view>

    <!-- 结算弹窗 -->
    <view v-if="!gameState?.gameStarted && gameState?.winnerId" class="modal-overlay">
      <view class="modal-content glass-card">
        <text class="modal-emoji">{{ gameState.winnerId === myUserId ? '🏆' : '💀' }}</text>
        <text class="modal-title">{{ gameState.winnerId === myUserId ? '胜利！' : '很遗憾失败了' }}</text>
        <view 
          class="btn-primary" 
          :class="{ disabled: isRefreshing }"
          @tap="refreshAndPlayAgain"
        >
          <text class="btn-text">🚀 再来一局</text>
        </view>
      </view>
    </view>

    <!-- 玩法说明弹窗 -->
    <view v-if="showGuide" class="modal-overlay" @tap="showGuide = false">
      <view class="guide-modal glass-card" @tap.stop>
        <view class="guide-header">
          <text class="guide-title">核心战书</text>
          <view class="close-btn" @tap="showGuide = false">✕</view>
        </view>
        <scroll-view scroll-y class="guide-body">
          <text class="section-title">🛡️ 道具百科</text>
          <view class="guide-grid">
            <view class="guide-item" v-for="(item, i) in guideItems" :key="'i'+i">
              <text class="icon">{{ item.i }}</text>
              <view class="desc">
                <text class="name">{{ item.n }}</text>
                <text class="detail">{{ item.d }}</text>
              </view>
            </view>
          </view>
          
          <text class="section-title" style="margin-top: 32rpx;">🐾 角色天赋</text>
          <view class="guide-grid">
            <view class="guide-item" v-for="(item, i) in characterGuides" :key="'c'+i">
              <text class="icon">{{ item.i }}</text>
              <view class="desc">
                <text class="name">{{ item.n }}</text>
                <text class="detail">{{ item.d }}</text>
              </view>
            </view>
          </view>
        </scroll-view>
      </view>
    </view>
    
    <!-- 全局飘字 -->
    <view v-for="l in globalLabels" :key="l.id" class="float-label global" :style="{ top: l.y + 'px', left: l.x + 'px' }" :class="'text-' + l.type">
      {{ l.text }}
    </view>

  </view>
</template>

<script>
import { nakamaManager } from '../../../utils/nakamaManager.js';

export default {
  data() {
    return {
      gameState: null,
      logs: [],
      isConnected: false,
      isMatching: false,
      matchId: null,
      myUserId: null,
      floatingLabels: [],
      showGuide: false,
      debugMode: false,
      matchingTimer: 0,
      matchPlayerCount: 4,
      turnTimer: 15,
      screenShaking: false,
      damagedPlayers: [],
      healedPlayers: [],
      isRefreshing: false,
      logsScrollTop: 0,
      // Timers
      matchInterval: null,
      turnInterval: null,
      
      guideItems: [
        { 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归零时复活' },
        { i: '⏰', n: '定时炸弹', d: '3回合后爆炸' },
        { i: '☠️', n: '毒药', d: '对手中毒每步扣血' },
        { i: '👻', n: '诅咒', d: '特定操作触发扣血' },
        { i: '📦', n: '宝箱', d: '随机大奖' },
      ],
      characterGuides: [
        { i: '🐶', n: '小狗', d: '忠诚：每移动一定步数必触发放大镜效果' },
        { i: '🐘', n: '大象', d: '执拗：无法回复生命，但基础HP更高' },
        { i: '🐯', n: '虎哥', d: '猛攻：匕首进化为全屏范围伤害' },
        { i: '🐵', n: '猴子', d: '敏锐：每次点击都有概率发现香蕉(回血)' },
        { i: '🦥', n: '树懒', d: '迟缓：翻到炸弹时伤害减半(扣1点)' },
        { i: '🦛', n: '河马', d: '大胃：无法直接捡起道具卡' },
      ]
    }
  },
  computed: {
    myPlayer() {
      if (!this.gameState || !this.gameState.players || !this.myUserId) return null;
      return this.gameState.players[this.myUserId];
    },
    opponents() {
      if (!this.gameState || !this.gameState.players || !this.myUserId) return [];
      return Object.values(this.gameState.players).filter(p => p.userId !== this.myUserId);
    },
    isMyTurn() {
      if (!this.gameState) return false;
      return this.gameState.turnOrder[this.gameState.currentTurnIndex] === this.myUserId;
    },
    globalLabels() {
      return this.floatingLabels.filter(l => l.cellIndex === undefined && l.targetUserId === undefined);
    }
  },
  watch: {
    logs() {
       this.$nextTick(() => {
         this.logsScrollTop = 99999 + Math.random(); 
       });
    },
    'gameState.currentTurnIndex'() {
       this.resetTurnTimer();
    },
    'gameState.gameStarted'(val) {
      if (val) this.resetTurnTimer();
    }
  },
  onLoad(options) {
    this.fetchGameConfig();
    const { game_token, nakama_server, nakama_key } = options;
    if (game_token) {
      this.initNakama(game_token, decodeURIComponent(nakama_server || ''), decodeURIComponent(nakama_key || ''));
    } else {
      uni.showToast({ title: '参数错误', icon: 'none' });
    }
  },
  onUnload() {
    this.cleanup();
  },
  methods: {
    async fetchGameConfig() {
       try {
          const res = await new Promise((resolve, reject) => {
            uni.request({
              url: 'https://game.1024tool.vip/api/internal/game/minesweeper/config',
              header: { 'X-Internal-Key': 'bindbox-internal-secret-2024' },
              success: (res) => resolve(res),
              fail: (err) => reject(err)
            })
          });
          if (res.statusCode === 200 && res.data) {
             const config = res.data;
             if (config.match_player_count && config.match_player_count >= 2) {
                this.matchPlayerCount = config.match_player_count;
             }
          }
       } catch(e) {
          console.warn('Config fetch failed');
       }
    },
    getCellLabels(idx) {
      return this.floatingLabels.filter(l => l.cellIndex === idx);
    },
    getPlayerLabels(userId) {
      return this.floatingLabels.filter(l => l.targetUserId === userId);
    },
    addLog(type, content) {
      const now = new Date();
      const timeStr = now.getHours().toString().padStart(2, '0') + ':' + now.getMinutes().toString().padStart(2, '0');
      const id = Date.now() + Math.random().toString();
      this.logs.push({ id, type, content, time: timeStr });
      if (this.logs.length > 50) this.logs.shift();
    },
    spawnLabel(x, y, text, type, cellIndex, targetUserId) {
      const id = Date.now() + Math.random().toString();
      this.floatingLabels.push({ id, x, y, text, type, cellIndex, targetUserId });
      setTimeout(() => {
        this.floatingLabels = this.floatingLabels.filter(l => l.id !== id);
      }, 1000);
    },
    async initNakama(token, server, key) {
      try {
        const serverUrl = server || 'wss://game.1024tool.vip';
        const serverKey = key || 'defaultkey';
        nakamaManager.initClient(serverUrl, serverKey);
        const session = await nakamaManager.authenticateWithGameToken(token);
        this.myUserId = session.user_id;
        this.isConnected = true;
        this.addLog('system', '✅ 已连接到远程节点');
        // 先设置监听器，再继续后续操作
        this.setupSocketListeners();
      } catch (e) {
        this.addLog('system', '❌ 通讯异常: ' + e.message);
      }
    },
    setupSocketListeners() {
      nakamaManager.setListeners({
        onmatchmakermatched: async (matched) => {
          // ========== 控制台日志 - 匹配成功 ==========
          console.log('=== 匹配成功事件 ===');
          console.log('[匹配时间]', new Date().toLocaleString());
          console.log('[Match ID]', matched.match_id);
          console.log('[Match Token]', matched.token ? '存在' : '不存在 (权威模式通常不需要)');
          console.log('[完整匹配对象]', JSON.stringify(matched, null, 2));
          console.log('==================');

          this.addLog('system', `📡 信号锁定！同步中...`);
          this.isMatching = false;
          clearInterval(this.matchInterval);

          // 保存匹配信息用于可能的重连
          this.pendingMatchId = matched.match_id;
          this.pendingMatchToken = matched.token;

          // 带重试的 joinMatch
          const maxRetries = 3;
          for (let i = 0; i < maxRetries; i++) {
            try {
              console.log(`[尝试 ${i + 1}/${maxRetries}] 开始加入游戏房间...`);
              const match = await nakamaManager.joinMatch(matched.match_id, matched.token);

              // ========== 控制台日志 - 加入成功 ==========
              console.log('=== 成功加入游戏房间 ===');
              console.log('[房间 ID]', match.match_id);
              console.log('[我的用户 ID]', this.myUserId);
              console.log('[房间对象]', JSON.stringify(match, null, 2));
              console.log('======================');

              this.matchId = match.match_id;
              this.addLog('system', `成功接入战局`);
              setTimeout(() => {
                console.log('[发送状态请求] 请求初始游戏状态...');
                nakamaManager.sendMatchState(match.match_id, 100, JSON.stringify({ action: 'getState' }));
              }, 100);
              return; // 成功，退出重试循环
            } catch (e) {
              // ========== 控制台日志 - 加入失败 ==========
              console.error(`[尝试 ${i + 1}/${maxRetries} 失败]`, e.message);
              console.error('[错误详情]', e);

              this.addLog('system', `⚠️ 接入尝试 ${i + 1}/${maxRetries} 失败: ${e.message}`);
              if (i < maxRetries - 1) {
                console.log(`等待 1 秒后重试...`);
                await new Promise(r => setTimeout(r, 1000)); // 等待1秒后重试
              }
            }
          }

          // ========== 控制台日志 - 最终失败 ==========
          console.error('=== 加入游戏房间最终失败 ===');
          console.error('[Match ID]', matched.match_id);
          console.error('[重试次数]', maxRetries);
          console.error('============================');

          this.addLog('system', `❌ 接入失败，请检查网络后重试`);
        },
        onmatchdata: (matchData) => {
          const opCode = matchData.op_code;
          // NakamaManager 已内部处理了 utf8 解码，直接 parse 即可
          // const data = JSON.parse(new TextDecoder().decode(matchData.data));
          const data = typeof matchData.data === 'string' ? JSON.parse(matchData.data) : matchData.data;

          // ========== 控制台日志 - 接收游戏数据 ==========
          console.log('=== 接收游戏数据 ===');
          console.log('[OpCode]', opCode, `(${this.getOpCodeName(opCode)})`);
          console.log('[数据]', data);
          console.log('[时间]', new Date().toLocaleString());
          console.log('====================');

          this.handleGameData(opCode, data);
        },
        ondisconnect: async () => {
          // ========== 控制台日志 - 断开连接 ==========
          console.warn('=== 连接断开 ===');
          console.warn('[断开时间]', new Date().toLocaleString());
          console.warn('[Match ID]', this.matchId);
          console.warn('===============');

          this.addLog('system', `⚠️ 连接断开，尝试重连中...`);
          this.isConnected = false;

          // 自动重连
          try {
            console.log('[重连] 开始重新连接...');
            await nakamaManager.authenticateWithGameToken(this.gameToken);
            this.isConnected = true;

            console.log('[重连] 认证成功');

            this.addLog('system', `✅ 重连成功`);

            // 如果有进行中的比赛，尝试重新加入
            if (this.matchId) {
              console.log('[重连] 尝试重新加入游戏房间:', this.matchId);
              const match = await nakamaManager.joinMatch(this.matchId);
              console.log('[重连] 成功重新加入游戏房间');

              this.addLog('system', `✅ 已重新加入战局`);
              nakamaManager.sendMatchState(this.matchId, 100, JSON.stringify({ action: 'getState' }));
            }
          } catch (e) {
            console.error('[重连] 失败:', e);
            this.addLog('system', `❌ 重连失败: ${e.message}`);
          }
        }
      });
    },
    handleGameData(opCode, data) {
      // 关键游戏状态的控制台日志
      if (opCode === 1) {
        // ========== 控制台日志 - 游戏开始 ==========
        console.log('🎮 ========== 游戏开始 ==========');
        console.log('[玩家数量]', Object.keys(data.players || {}).length);
        console.log('[我的位置]', data.turnOrder?.indexOf(this.myUserId));
        console.log('[网格大小]', data.gridSize);
        console.log('[游戏状态]', data);
        console.log('[DEBUG] myUserId:', this.myUserId);
        console.log('[DEBUG] turnOrder:', data.turnOrder);
        console.log('[DEBUG] currentTurnIndex:', data.currentTurnIndex);
        console.log('[DEBUG] 当前回合玩家:', data.turnOrder?.[data.currentTurnIndex]);
        console.log('[DEBUG] isMyTurn?', data.turnOrder?.[data.currentTurnIndex] === this.myUserId);
        console.log('================================');
      } else if (opCode === 6) {
        // ========== 控制台日志 - 游戏结束 ==========
        console.log('🏁 ========== 游戏结束 ==========');
        console.log('[获胜者]', data.winnerId);
        console.log('[是否胜利]', data.winnerId === this.myUserId);
        console.log('[最终状态]', data);
        console.log('================================');
      }

      if (opCode === 1) {
        this.gameState = data;
        this.addLog('system', '战局开始，准备翻格！');
      } else if (opCode === 2) {
        // 状态更新 - 检测 HP 变化触发特效
        const prevState = this.gameState;
        if (prevState && prevState.players) {
           Object.keys(data.players || {}).forEach(uid => {
             const prevP = prevState.players[uid];
             const newP = data.players[uid];
             if (!prevP || !newP) return;

             const hpDiff = newP.hp - prevP.hp;
             if (hpDiff < 0) {
               // 受伤
               const dmg = Math.abs(hpDiff);
               this.spawnLabel(0, 0, `-${dmg}`, 'damage', undefined, uid);
               this.triggerDamageEffect(uid, dmg);
             } else if (hpDiff > 0) {
               // 治疗
               const heal = Math.abs(hpDiff);
               this.spawnLabel(0, 0, `+${heal}`, 'heal', undefined, uid);
               this.healedPlayers.push(uid);
               setTimeout(() => this.healedPlayers = this.healedPlayers.filter(id => id !== uid), 600);
             }
           });
        }
        this.gameState = data;
      } else if (opCode === 5) {
        this.handleEvent(data);
      } else if (opCode === 6) {
        if (data.gameState) {
           this.gameState = data.gameState;
        } else {
           this.gameState = data;
        }
        this.addLog('system', `战局结束：${data.winnerId === this.myUserId ? '您获得了胜利！' : '很遗憾失败了'}`);
      }
    },
    handleEvent(event) {
      if (event.type === 'damage' || event.type === 'heal' || event.type === 'item' || event.type === 'ability') {
        const isMe = event.targetUserId === this.myUserId;
        const iAmTarget = isMe;
        const attackerName = event.playerName || '对手';
        const itemDisplayName = this.guideItems.find(i => i.i === event.itemId)?.n || event.itemId;
        
        let msg = '';
        if (event.type === 'item') msg = `发现了 ${itemDisplayName}`;
        else if (event.type === 'damage') msg = `受到了 ${event.value} 点伤害`;
        else if (event.type === 'heal') msg = `回复了 ${event.value} 点生命`;

        if (isMe) this.addLog('effect', `指令提示: ${msg}`);
        else this.addLog('effect', `${attackerName.substring(0,8)}: ${msg}`);

        if (event.type === 'damage' || event.type === 'item') {
           if (iAmTarget && event.value) this.spawnLabel(0, 0, `-${event.value}`, 'damage', undefined, this.myUserId);
        }
        // 对于 opCode 5 的 damage 事件，也触发特效（通常 opCode 2 会覆盖，但多触发一次无妨，作为保险）
        if (event.type === 'damage' && iAmTarget) this.triggerDamageEffect(this.myUserId, event.value);
      }
    },
    triggerDamageEffect(uid, amount) {
       this.damagedPlayers.push(uid);
       setTimeout(() => this.damagedPlayers = this.damagedPlayers.filter(id => id !== uid), 600);
       if (uid === this.myUserId) {
         this.screenShaking = true;
         setTimeout(() => this.screenShaking = false, 400);
       }
    },
    async startMatchmaking() {
      if (this.isMatching) return;
      try {
        console.log('--- UI Click: Start Matchmaking ---');
        this.isMatching = true;
        this.matchingTimer = 0;
        this.logs = []; 
        this.addLog('system', '🚀 发射匹配脉冲...');
        
        clearInterval(this.matchInterval);
        this.matchInterval = setInterval(() => this.matchingTimer++, 1000);
        
        await nakamaManager.findMatch(this.matchPlayerCount, this.matchPlayerCount);
        console.log('Matchmaker ticket requested');
      } catch (e) {
        console.error('Matchmaking error:', e);
        this.isMatching = false;
        clearInterval(this.matchInterval);
        this.addLog('system', '❌ 发射失败');
      }
    },
    cancelMatchmaking() {
      this.isMatching = false;
      clearInterval(this.matchInterval);
      this.addLog('system', '已切断匹配信号');
    },
    handleCellClick(idx) {
      if (!this.gameState || !this.gameState.gameStarted) return;
      if (!this.isMyTurn) return;
      if (this.gameState.grid[idx].revealed) return;
      nakamaManager.sendMatchState(this.matchId, 3, JSON.stringify({ index: idx }));
    },
    refreshAndPlayAgain() {
       uni.navigateBack();
    },
    resetTurnTimer() {
      this.turnTimer = 15;
      clearInterval(this.turnInterval);
      this.turnInterval = setInterval(() => {
        if (this.turnTimer > 0) this.turnTimer--;
      }, 1000);
    },
    cleanup() {
      clearInterval(this.matchInterval);
      clearInterval(this.turnInterval);
      nakamaManager.disconnect();
    },
    getItemIcon(itemId) {
      const map = { medkit: '💊', bomb_timer: '⏰', poison: '☠️', shield: '🛡️', skip: '⏭️', magnifier: '🔍', knife: '🔪', revive: '💖', lightning: '⚡', chest: '📦', curse: '👻' };
      return map[itemId] || '🎁';
    },
    getContentIcon(content) {
      if (content === 'bomb') return '💣';
      if (content === 'empty') return '✅';
      return this.getItemIcon(content);
    },
    getPlayerAvatar(player) {
      // 优先从 character 字段获取 emoji
      const charAvatars = {
        dog: '🐶',
        elephant: '🐘',
        tiger: '🐯',
        monkey: '🐵',
        sloth: '🦥',
        hippo: '🦛',
        cat: '🐱',
        chicken: '🐔'
      };
      if (player.character && charAvatars[player.character]) {
        return charAvatars[player.character];
      }

      // 如果服务器直接发送了 avatar 字段
      if (player.avatar) return player.avatar;

      // 降级：根据 userId 确定性分配
      const avatars = ['🐶', '🐘', '🐯', '🐵', '🦥', '🦛'];
      const seed = player.userId || player.username || player.id || '';
      let hash = 0;
      for (let i = 0; i < seed.length; i++) {
        hash = ((hash << 5) - hash) + seed.charCodeAt(i);
        hash = hash & hash; // 转换为32位整数
      }
      const index = Math.abs(hash) % avatars.length;
      return avatars[index];
    },
    getNumColor(n) { return ['','blue','green','red','purple','orange'][n] || 'black'; },
    getOpCodeName(code) {
      const map = {
        1: '游戏开始',
        2: '状态更新',
        3: '玩家点击格子',
        5: '游戏事件',
        6: '游戏结束',
        100: '请求游戏状态'
      };
      return map[code] || '未知';
    }
  }
}
</script>

<style src="./play.scss" lang="scss"></style>
