/**
 * MenuScene.js
 * Main menu scene — military-tech themed UI with game title and mode selection.
 * Rendered entirely with Canvas API (no DOM).
 */

const {
  SCREEN_WIDTH,
  SCREEN_HEIGHT,
  COLORS,
  SCENE,
  GAME_MODE,
} = require('../base/GameGlobal');
const { t } = require('../i18n/I18n');

// ============================================================
// Style — Military-tech theme matching reference design
// ============================================================
const MC = {
  BG_TOP: '#0a0e1a',
  BG_BOT: '#111827',
  ACCENT: '#e94560',
  GOLD: '#FFD700',
  GOLD_LIGHT: '#FFF3A8',
  GOLD_DIM: '#B8860B',
  BTN_BG: '#162844',
  BTN_BG_HIGHLIGHT: '#1a3555',
  BG_GRAD_START: '#142236',
  BG_GRAD_END: '#0c1320',
  BTN_BORDER_GLOW: 'rgba(70,140,220,0.4)',
  BTN_BORDER: 'rgba(50,100,170,0.5)',
  BTN_HOVER: '#244a75',
  BTN_TEXT_PRIMARY: '#FFFFFF',
  BTN_TEXT_SECONDARY: '#88AACC',
  TITLE: '#FFD700',
  SUBTITLE_BG: 'rgba(25,55,95,0.85)',
  SUBTITLE_BORDER: '#3a68a0',
  SUBTITLE_TEXT: '#7CB9E8',
  FOOTER: '#445566',
  ICON_GOLD: '#FFD700',
  ICON_BLUE: '#4A90D9',
  HOT_BADGE: '#e94560',
  UTIL_GREEN: '#1a4a2e',
};

// ============================================================
// Layout — Left-Right Split (Reference Design)
//
//   ┌─ Left Panel (~54%) ─┬─ Right Panel (~43%) ─┐
//   │  Tank visual area    │  5 mode buttons       │
//   │  + Title + Subtitle  │  (vertical stack)     │
//   │  + Promo text        │                       │
//   ├──────────────────────┴───────────────────────┤
//   │         Bottom Utility Bar (4 columns)        │
//   └───────────────────────────────────────────────┘
// ============================================================

const PAD = Math.max(12, SCREEN_WIDTH * 0.03);
const TOP_BAR_H = 48;
const SPLIT_X = SCREEN_WIDTH * 0.55;
const RIGHT_PAD = Math.max(14, PAD * 2);

// --- Right Panel: Mode Buttons (vertical) ---
const MODE_INNER_PAD = PAD; // inner left padding inside right panel
const MODE_BTN_W = SCREEN_WIDTH - SPLIT_X - RIGHT_PAD - MODE_INNER_PAD;
const MODE_BTN_H = Math.min(66, SCREEN_HEIGHT * 0.095);
const MODE_GAP = Math.max(10, SCREEN_HEIGHT * 0.015);
const MODE_START_Y = TOP_BAR_H + SCREEN_HEIGHT * 0.035;

// --- Bottom Utility Bar ---
const UTIL_BAR_Y = SCREEN_HEIGHT * 0.805;
const UTIL_BAR_H = Math.min(58, SCREEN_HEIGHT * 0.088);
const UTIL_EDGE_PAD = Math.max(24, SCREEN_WIDTH * 0.058);
const UTIL_GAP = Math.max(14, SCREEN_WIDTH * 0.025);
const UTIL_COL_W = (SCREEN_WIDTH - UTIL_EDGE_PAD * 2 - UTIL_GAP * 3) / 4;

// ============================================================
// Button Definitions
// ============================================================

const MAIN_BUTTONS = [
  { labelKey: 'menu.classic', subKey: 'menu.classic.sub', icon: 'trophy', mode: GAME_MODE.CLASSIC, scene: SCENE.GAME },
  { labelKey: 'menu.endless', subKey: 'menu.endless.sub', icon: 'target', mode: GAME_MODE.ENDLESS, scene: SCENE.GAME },
  { labelKey: 'menu.pvp', subKey: 'menu.pvp.sub', icon: 'swords', mode: GAME_MODE.PVP, scene: SCENE.PVP_ROOM },
  { labelKey: 'menu.team2v2', subKey: 'menu.team2v2.sub', icon: 'swords', mode: GAME_MODE.TEAM_2V2, scene: SCENE.TEAM_2V2_ROOM },
  { labelKey: 'menu.team3v3', subKey: 'menu.team3v3.sub', icon: 'shield', mode: GAME_MODE.TEAM_3V3, scene: SCENE.TEAM_ROOM, hot: true },
];

const UTIL_BUTTONS = [
  { labelKey: 'dailyGold.btn', subKey: 'dailyGold.desc', icon: 'coins', mode: null, scene: 'DAILY_GOLD' },
  { labelKey: 'menu.skin', subKey: 'menu.skin.sub', icon: 'skin', mode: null, scene: SCENE.SKIN },
  { labelKey: 'menu.ranking', subKey: 'menu.ranking.sub', icon: 'ranking', mode: null, scene: SCENE.RANKING },
  { labelKey: 'menu.settings', subKey: 'menu.settings.sub', icon: 'settings', mode: null, scene: SCENE.SETTINGS },
];

// Pre-calculate mode button rects (right panel, vertical stack)
const mainBtnRects = MAIN_BUTTONS.map((btn, i) => ({
  x: SPLIT_X + MODE_INNER_PAD,
  y: MODE_START_Y + i * (MODE_BTN_H + MODE_GAP),
  w: MODE_BTN_W,
  h: MODE_BTN_H,
  ...btn,
}));

// Pre-calculate utility button rects (bottom row)
const utilBtnRects = UTIL_BUTTONS.map((btn, i) => ({
  x: UTIL_EDGE_PAD + i * (UTIL_COL_W + UTIL_GAP),
  y: UTIL_BAR_Y,
  w: UTIL_COL_W,
  h: UTIL_BAR_H,
  ...btn,
}));

const buttonRects = [...mainBtnRects, ...utilBtnRects];

// ============================================================
// Menu Scene
// ============================================================
const MenuScene = {
  _pressedIndex: -1,
  _tankAnim: 0,

  // Background image
  _bgImage: null,

  enter() {
    this._pressedIndex = -1;
    this._tankAnim = 0;
    this._avatarImg = null;
    this._bgImage = null;

    // Load background image
    this._loadBgImage();

    // Load avatar image if profile has one
    const profile = GameGlobal.playerProfile;
    if (profile && profile.avatarUrl) {
      this._loadAvatarImage(profile.avatarUrl);
    }

    // Listen for profile updates (avatar may arrive after initial render)
    this._profileHandler = (data) => {
      if (data && data.avatarUrl && !this._avatarImg) {
        this._loadAvatarImage(data.avatarUrl);
      }
    };
    const bus = GameGlobal.eventBus;
    if (bus && typeof bus.on === 'function') {
      bus.on('profile:updated', this._profileHandler);
    }

    // Kick off nickname acquisition as early as possible so that later
    // network messages (CREATE_TEAM, SOLO_MATCH, ...) can carry it.
    this._initPlayerProfile();

    if (GameGlobal._pendingTeamId) {
      const teamId = GameGlobal._pendingTeamId;
      const teamMode = GameGlobal._pendingTeamMode || null;
      GameGlobal._pendingTeamId = null;
      GameGlobal._pendingTeamMode = null;
      const is2v2 = teamMode === '2v2';
      const targetScene = is2v2 ? SCENE.TEAM_2V2_ROOM : SCENE.TEAM_ROOM;
      const sceneName = is2v2 ? 'Team2v2RoomScene' : 'TeamRoomScene';
      console.log(`[MenuScene] Found pendingTeamId: ${teamId}, mode: ${teamMode || '3v3'}, will auto-navigate to ${sceneName}`);
      setTimeout(() => {
        console.log(`[MenuScene] Auto-navigating to ${sceneName} with teamId: ${teamId}`);
        const sm = GameGlobal.sceneManager;
        if (!sm._scenes.has(targetScene)) {
          const SceneModule = is2v2
            ? require('./Team2v2RoomScene')
            : require('./TeamRoomScene');
          sm.register(targetScene, SceneModule);
        }
        sm.switchTo(targetScene, { teamId });
      }, 100);
    }

    if (GameGlobal._pendingRoomId) {
      const roomId = GameGlobal._pendingRoomId;
      GameGlobal._pendingRoomId = null;
      console.log(`[MenuScene] Found pendingRoomId: ${roomId}, will auto-navigate to RoomScene`);
      setTimeout(() => {
        console.log(`[MenuScene] Auto-navigating to RoomScene with roomId: ${roomId}`);
        const sm = GameGlobal.sceneManager;
        if (!sm._scenes.has(SCENE.PVP_ROOM)) {
          const RoomScene = require('./RoomScene');
          sm.register(SCENE.PVP_ROOM, RoomScene);
        }
        sm.switchTo(SCENE.PVP_ROOM, { roomId });
      }, 100);
    }
  },

  exit() {
    this._pressedIndex = -1;
    // Destroy UserInfoButton overlay when leaving the menu
    const profile = GameGlobal.playerProfile;
    if (profile && typeof profile.destroyUserInfoButton === 'function') {
      profile.destroyUserInfoButton();
    }
    // Remove profile update listener
    const bus = GameGlobal.eventBus;
    if (bus && typeof bus.off === 'function' && this._profileHandler) {
      bus.off('profile:updated', this._profileHandler);
    }
    this._profileHandler = null;
    this._avatarImg = null;
  },

  update(dt) {
    this._tankAnim += dt;
  },

  render(ctx) {
    // ---- Background (image or fallback gradient) ----
    if (this._bgImage) {
      // Cover-fit: scale image to fill entire screen, center-crop if aspect differs
      const imgW = this._bgImage.width;
      const imgH = this._bgImage.height;
      const imgRatio = imgW / imgH;
      const screenRatio = SCREEN_WIDTH / SCREEN_HEIGHT;
      var drawW, drawH, dx, dy;
      if (imgRatio > screenRatio) {
        drawH = SCREEN_HEIGHT;
        drawW = SCREEN_HEIGHT * imgRatio;
        dx = (SCREEN_WIDTH - drawW) / 2;
        dy = 0;
      } else {
        drawW = SCREEN_WIDTH;
        drawH = SCREEN_WIDTH / imgRatio;
        dx = 0;
        dy = (SCREEN_HEIGHT - drawH) / 2;
      }
      ctx.drawImage(this._bgImage, dx, dy, drawW, drawH);
    } else {
      const bgGrad = ctx.createLinearGradient(0, 0, 0, SCREEN_HEIGHT);
      bgGrad.addColorStop(0, MC.BG_TOP);
      bgGrad.addColorStop(1, MC.BG_BOT);
      ctx.fillStyle = bgGrad;
      ctx.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

      // Scan-lines
      ctx.globalAlpha = 0.02;
      ctx.fillStyle = '#FFFFFF';
      for (let sy = 0; sy < SCREEN_HEIGHT; sy += 4) {
        ctx.fillRect(0, sy, SCREEN_WIDTH, 1);
      }
      ctx.globalAlpha = 1;
    }

    // Top accent bar
    const accentGrad = ctx.createLinearGradient(0, 0, SCREEN_WIDTH, 0);
    accentGrad.addColorStop(0, 'transparent');
    accentGrad.addColorStop(0.3, MC.ACCENT);
    accentGrad.addColorStop(0.7, MC.ACCENT);
    accentGrad.addColorStop(1, 'transparent');
    ctx.fillStyle = accentGrad;
    ctx.fillRect(0, 0, SCREEN_WIDTH, 3);

    // ============================================================
    // LEFT PANEL — Branding area (~54% width)
    //   - Tank icon (animated)
    //   - Title + subtitle tag
    //   - Decorative treasure icon
    //   - Promotional text
    // ============================================================
    const leftCenterX = SPLIT_X * 0.5;
    const leftCenterY = SCREEN_HEIGHT * 0.48;

    // ---- Animated Tank Icon (larger, as visual anchor) ----
    ctx.save();
    ctx.translate(leftCenterX * 0.65, leftCenterY - 10);
    const tankScale = 1.6;
    ctx.scale(tankScale, tankScale);
    ctx.translate(-leftCenterX * 0.65 / tankScale, (-leftCenterY + 10) / tankScale);
    this._drawTankIcon(ctx, leftCenterX * 0.65, (leftCenterY - 10) / tankScale);
    ctx.restore();

    // ---- Title (positioned in upper-right of left panel) ----
    const titleX = SPLIT_X * 0.52;
    const titleY = TOP_BAR_H + SCREEN_HEIGHT * 0.04;
    ctx.save();
    ctx.shadowColor = MC.GOLD;
    ctx.shadowBlur = 22;
    ctx.fillStyle = MC.TITLE;
    const titleSize = Math.max(Math.min(SPLIT_X * 0.13, 38), 26);
    ctx.font = `bold ${titleSize}px Arial`;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(t('menu.title'), titleX, titleY);

    // Subtitle tag below title
    ctx.shadowBlur = 0;
    const subText = t('menu.subtitle');
    const sFont = '11px Arial';
    ctx.font = sFont;
    const stw = ctx.measureText(subText).width;
    const stagW = Math.max(stw + 20, 120);
    const stagH = 24;
    const stagX = titleX - stagW / 2;
    const stagY = titleY + titleSize * 0.58;

    ctx.fillStyle = MC.SUBTITLE_BG;
    ctx.strokeStyle = MC.SUBTITLE_BORDER;
    ctx.lineWidth = 1.2;
    this._roundRect(ctx, stagX, stagY, stagW, stagH, stagH / 2);
    ctx.fill();
    ctx.stroke();

    ctx.fillStyle = MC.SUBTITLE_TEXT;
    ctx.font = sFont;
    ctx.fillText(subText, titleX, stagY + stagH / 2);
    ctx.restore();

    // ---- Promotional Text (bottom-left) ----
    ctx.save();
    const promoY = UTIL_BAR_Y - 38;
    const promoX = PAD * 3.2;

    // "3v3 团队竞技" style text
    ctx.fillStyle = '#4A9EFF';
    ctx.font = `bold ${Math.max(16, SCREEN_WIDTH * 0.042)}px Arial`;
    ctx.textAlign = 'left';
    ctx.textBaseline = 'bottom';

    // Add subtle glow
    ctx.shadowColor = '#4A9EFF';
    ctx.shadowBlur = 8;
    const promoLine1 = '3v3 团队竞技';
    ctx.fillText(promoLine1, promoX, promoY);

    // "随时随地开一局！" style text
    ctx.shadowBlur = 0;
    ctx.fillStyle = '#FFD54F';
    ctx.font = `bold ${Math.max(14, SCREEN_WIDTH * 0.037)}px Arial`;
    const promoLine2 = '随时随地开一局！';
    ctx.fillText(promoLine2, promoX, promoY + 32);
    ctx.restore();

    // ============================================================
    // RIGHT PANEL — Mode buttons (vertical stack)
    // ============================================================
    for (let i = 0; i < mainBtnRects.length; i++) {
      const btn = mainBtnRects[i];
      const isPressed = this._pressedIndex === i;
      this._drawModeButton(
        ctx, btn,
        t(btn.labelKey),
        isPressed,
        null,
        t(btn.subKey || ''),
        btn.icon,
        !!btn.hot
      );
    }

    // ============================================================
    // TOP BAR — Avatar + Gold pill
    // ============================================================
    // Player Avatar & Nickname (top-left)
    const profile = GameGlobal.playerProfile;
    const avatarSize = 28;
    const avatarX = PAD;
    const avatarY = 8;
    const avatarR = avatarSize / 2;

    ctx.save();
    ctx.beginPath();
    ctx.arc(avatarX + avatarR, avatarY + avatarR, avatarR, 0, Math.PI * 2);
    ctx.closePath();
    ctx.fillStyle = 'rgba(30,48,84,0.75)';
    ctx.fill();
    ctx.strokeStyle = 'rgba(255,215,0,0.45)';
    ctx.lineWidth = 1.2;
    ctx.stroke();

    if (profile && profile.avatarUrl && this._avatarImg && this._avatarImg.complete) {
      ctx.clip();
      ctx.drawImage(this._avatarImg, avatarX, avatarY, avatarSize, avatarSize);
    } else {
      ctx.fillStyle = 'rgba(255,215,0,0.5)';
      ctx.beginPath();
      ctx.arc(avatarX + avatarR, avatarY + avatarR - 2, avatarR * 0.35, 0, Math.PI * 2);
      ctx.fill();
      ctx.beginPath();
      ctx.ellipse(avatarX + avatarR, avatarY + avatarR + avatarR * 0.55, avatarR * 0.55, avatarR * 0.3, 0, Math.PI, 0);
      ctx.fill();
    }
    ctx.restore();

    // Nickname next to avatar
    const displayName = profile ? profile.getDisplayName() : 'Tanker';
    ctx.font = 'bold 11px Arial';
    ctx.fillStyle = MC.GOLD;
    ctx.textAlign = 'left';
    ctx.textBaseline = 'middle';
    ctx.fillText(displayName, avatarX + avatarSize + 6, avatarY + avatarR - 5);
    if (profile && !profile.granted) {
      ctx.font = '9px Arial';
      ctx.fillStyle = MC.FOOTER;
      ctx.fillText(t('menu.tapToAuth') || 'Tap to authorize', avatarX + avatarSize + 6, avatarY + avatarR + 8);
    }

    // Gold Balance pill (to the right of nickname)
    const gold = GameGlobal.currencyManager ? GameGlobal.currencyManager.getGold() : 0;
    const goldText = `🪙 ${gold}`;
    ctx.font = 'bold 12px Arial';
    const gtw = ctx.measureText(goldText).width;
    const pillW = gtw + 14;
    const pillH = 22;
    const pillX = avatarX + avatarSize + 6;  // right under nickname
    const pillY = avatarY + avatarR + 12;

    ctx.fillStyle = 'rgba(255,215,0,0.08)';
    ctx.strokeStyle = 'rgba(255,215,0,0.35)';
    ctx.lineWidth = 1;
    this._roundRect(ctx, pillX, pillY, pillW, pillH, pillH / 2);
    ctx.fill();
    ctx.stroke();
    ctx.fillStyle = MC.GOLD;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(goldText, pillX + pillW / 2, pillY + pillH / 2);

    // ============================================================
    // BOTTOM UTILITY BAR — 4 columns
    // ============================================================
    for (let i = 0; i < utilBtnRects.length; i++) {
      const btn = utilBtnRects[i];
      const globalIdx = mainBtnRects.length + i;
      const isPressed = this._pressedIndex === globalIdx;

      let label = t(btn.labelKey);
      let subtitle = t(btn.subKey || '');
      let customBg = null;
      let iconOverride = btn.icon;

      if (btn.scene === 'DAILY_GOLD') {
        const remaining = GameGlobal.adManager ? GameGlobal.adManager.getDailyGoldRemaining() : 0;
        if (remaining > 0) {
          label = `${t('dailyGold.btn')} ${remaining}/3`;
          subtitle = t('dailyGold.desc') || '';
          customBg = MC.UTIL_GREEN;
          iconOverride = 'coins';
        } else {
          label = t('dailyGold.exhausted') || '...';
          subtitle = '';
          customBg = '#222';
          iconOverride = 'coins';
        }
      }

      this._drawUtilButton(ctx, btn, label, subtitle, isPressed, customBg, iconOverride);
    }

    // ---- Footer version ----
    ctx.fillStyle = MC.FOOTER;
    ctx.font = `${Math.max(9, SCREEN_WIDTH * 0.022)}px Arial`;
    ctx.textAlign = 'center';
    ctx.fillText('v1.0.0', SCREEN_WIDTH / 2, SCREEN_HEIGHT - 10);
  },

  // ---- Mode Button (Right panel: icon + two-line text + optional hot badge) ----
  _drawModeButton(ctx, btn, label, isPressed, font, subtitle, iconType, isHot) {
    const r = 10;
    ctx.save();
    ctx.globalAlpha = 0.85;

    const iconSz = Math.max(26, Math.min(btn.h * 0.48, 34));
    const pad = Math.max(10, iconSz * 0.38);
    const txtOff = iconSz + pad + 6;
    const iconX = btn.x + pad;
    const iconY = btn.y + (btn.h - iconSz) / 2;
    const textX = btn.x + txtOff;

    // Shadow
    ctx.fillStyle = 'rgba(0,0,0,0.35)';
    this._roundRect(ctx, btn.x + 2, btn.y + 3, btn.w, btn.h, r);
    ctx.fill();

    // Body gradient — slightly lighter for mode buttons
    const bodyGrad = ctx.createLinearGradient(btn.x, btn.y, btn.x, btn.y + btn.h);
    if (isPressed) {
      bodyGrad.addColorStop(0, '#284a70');
      bodyGrad.addColorStop(1, '#1c3055');
    } else if (isHot) {
      bodyGrad.addColorStop(0, '#1a4080');
      bodyGrad.addColorStop(1, '#142d55');
    } else {
      bodyGrad.addColorStop(0, MC.BTN_BG_HIGHLIGHT);
      bodyGrad.addColorStop(1, MC.BTN_BG);
    }
    ctx.fillStyle = bodyGrad;

    // Border glow
    if (isHot) {
      ctx.strokeStyle = 'rgba(100,180,255,0.6)';
      ctx.lineWidth = 1.5;
    } else {
      ctx.strokeStyle = isPressed ? MC.GOLD : MC.BTN_BORDER_GLOW;
      ctx.lineWidth = isPressed ? 2 : 1.2;
    }
    this._roundRect(ctx, btn.x, btn.y, btn.w, btn.h, r);
    ctx.fill();
    ctx.stroke();

    // Inner top highlight
    if (!isPressed) {
      ctx.save();
      ctx.clip();
      const hl = ctx.createLinearGradient(btn.x, btn.y, btn.x, btn.y + btn.h * 0.32);
      hl.addColorStop(0, isHot ? 'rgba(100,180,255,0.12)' : 'rgba(255,255,255,0.08)');
      hl.addColorStop(1, 'rgba(255,255,255,0)');
      ctx.fillStyle = hl;
      ctx.fillRect(btn.x, btn.y, btn.w, btn.h * 0.32);
      ctx.restore();
    }

    // Icon
    if (iconType) {
      this._drawButtonIcon(ctx, iconX, iconY, iconSz, iconType, isPressed);
    }

    // Two-line text — larger fonts with clear vertical separation
    const pFont = font || `bold ${Math.max(15, btn.h * 0.32)}px Arial`;
    const sFont = `${Math.max(11, btn.h * 0.24)}px Arial`;

    if (subtitle) {
      ctx.fillStyle = isPressed ? MC.GOLD_LIGHT : MC.BTN_TEXT_PRIMARY;
      ctx.font = pFont;
      ctx.textAlign = 'left';
      ctx.textBaseline = 'middle';
      ctx.fillText(label, textX, btn.y + btn.h * 0.33);

      ctx.fillStyle = isPressed ? 'rgba(200,220,255,0.85)' : MC.BTN_TEXT_SECONDARY;
      ctx.font = sFont;
      ctx.fillText(subtitle, textX, btn.y + btn.h * 0.73);
    } else {
      ctx.fillStyle = isPressed ? MC.TITLE : MC.BTN_TEXT_PRIMARY;
      ctx.font = pFont;
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillText(label, btn.x + btn.w / 2, btn.y + btn.h / 2);
    }

    // Hot badge ("火爆" style corner badge)
    if (isHot && !isPressed) {
      const badgeW = 34;
      const badgeH = 18;
      const bx = btn.x + btn.w - badgeW - 2;
      const by = btn.y + 2;

      ctx.save();
      ctx.fillStyle = MC.HOT_BADGE;
      this._roundRect(ctx, bx, by, badgeW, badgeH, 4);
      ctx.fill();

      ctx.fillStyle = '#FFFFFF';
      ctx.font = 'bold 10px Arial';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillText('HOT', bx + badgeW / 2, by + badgeH / 2);
      ctx.restore();
    }

    ctx.restore();
  },

  /**
   * Draw decorative treasure/chest icon in left panel.
   */
  _drawTreasureIcon(ctx, cx, cy) {
    const pulse = 0.5 + 0.5 * Math.sin(this._tankAnim * 1.8);
    const size = 36;
    ctx.save();

    // Glow halo
    ctx.globalAlpha = 0.12 + pulse * 0.1;
    ctx.fillStyle = MC.GOLD;
    ctx.beginPath();
    ctx.arc(cx, cy, size * 0.7, 0, Math.PI * 2);
    ctx.fill();
    ctx.globalAlpha = 1;

    // Chest body (rounded rectangle with metallic look)
    const bw = size * 0.85;
    const bh = size * 0.65;
    const br = 5;

    // Shadow
    ctx.fillStyle = 'rgba(0,0,0,0.25)';
    this._roundRect(ctx, cx - bw / 2 + 2, cy - bh / 2 + 3, bw, bh, br);
    ctx.fill();

    // Body gradient
    const chestGrad = ctx.createLinearGradient(cx - bw / 2, cy - bh / 2, cx - bw / 2, cy + bh / 2);
    chestGrad.addColorStop(0,   '#FFD54F');
    chestGrad.addColorStop(0.3, MC.GOLD);
    chestGrad.addColorStop(0.7, '#DAA520');
    chestGrad.addColorStop(1,   '#B8860B');

    ctx.save();
    ctx.shadowColor = MC.GOLD;
    ctx.shadowBlur = 12 + pulse * 5;
    ctx.fillStyle = chestGrad;
    this._roundRect(ctx, cx - bw / 2, cy - bh / 2, bw, bh, br);
    ctx.fill();
    ctx.restore();

    // Edge outline
    ctx.strokeStyle = 'rgba(255,235,150,0.6)';
    ctx.lineWidth = 1;
    this._roundRect(ctx, cx - bw / 2, cy - bh / 2, bw, bh, br);
    ctx.stroke();

    // Center lock/keyhole area
    const lockR = size * 0.14;
    ctx.fillStyle = '#7A5A0A';
    ctx.beginPath();
    ctx.arc(cx, cy, lockR, 0, Math.PI * 2);
    ctx.fill();

    // Keyhole inner
    ctx.fillStyle = '#FFF3A8';
    ctx.beginPath();
    ctx.arc(cx, cy - 1, lockR * 0.45, 0, Math.PI * 2);
    ctx.fill();
    ctx.fillRect(cx - 1.5, cy, 3, lockR * 0.6);

    // Horizontal lid line
    ctx.strokeStyle = 'rgba(120,80,0,0.5)';
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.moveTo(cx - bw * 0.38, cy - 2);
    ctx.lineTo(cx - lockR * 1.3, cy - 2);
    ctx.moveTo(cx + lockR * 1.3, cy - 2);
    ctx.lineTo(cx + bw * 0.38, cy - 2);
    ctx.stroke();

    // Decorative rivets
    ctx.fillStyle = '#B8860B';
    for (const [rx, ry] of [[-bw * 0.32, -bh * 0.25], [bw * 0.32, -bh * 0.25],
                             [-bw * 0.32, bh * 0.25], [bw * 0.32, bh * 0.25]]) {
      ctx.beginPath();
      ctx.arc(cx + rx, cy + ry, 2.2, 0, Math.PI * 2);
      ctx.fill();
    }

    ctx.restore();
  },

  /**
   * Draw button icons — simplified vector-style icons for each button type.
   * @param {CanvasRenderingContext2D} ctx
   * @param {number} x - left position
   * @param {number} y - top position
   * @param {number} size - icon size (square)
   * @param {string} type - icon identifier
   * @param {boolean} isActive - pressed/highlighted state
   */
  _drawButtonIcon(ctx, x, y, size, type, isActive) {
    const cx = x + size / 2;
    const cy = y + size / 2;
    const s = size / 2.2; // drawing scale

    ctx.save();

    // Icon glow when active
    if (isActive) {
      ctx.shadowColor = MC.GOLD;
      ctx.shadowBlur = 8;
    }

    const baseColor = isActive ? MC.GOLD_LIGHT : MC.ICON_GOLD;
    const dimColor = isActive ? '#E0B020' : MC.GOLD_DIM;

    switch (type) {
      case 'trophy': {
        // Trophy cup
        ctx.fillStyle = baseColor;
        ctx.beginPath();
        ctx.moveTo(cx - s * 0.5, cy - s * 0.7);
        ctx.lineTo(cx + s * 0.5, cy - s * 0.7);
        ctx.lineTo(cx + s * 0.35, cy - s * 0.1);
        ctx.lineTo(cx - s * 0.35, cy - s * 0.1);
        ctx.closePath();
        ctx.fill();
        // Cup base
        ctx.fillRect(cx - s * 0.25, cy - s * 0.1, s * 0.5, s * 0.35);
        ctx.fillRect(cx - s * 0.45, cy + s * 0.2, s * 0.9, s * 0.15);
        // Handles
        ctx.strokeStyle = baseColor;
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.arc(cx - s * 0.5, cy - s * 0.3, s * 0.25, Math.PI * 0.6, Math.PI * 1.4);
        ctx.stroke();
        ctx.beginPath();
        ctx.arc(cx + s * 0.5, cy - s * 0.3, s * 0.25, -Math.PI * 0.4, Math.PI * 0.4);
        ctx.stroke();
        break;
      }

      case 'target': {
        // Crosshair target
        ctx.strokeStyle = baseColor;
        ctx.lineWidth = 2.5;
        // Outer circle
        ctx.beginPath();
        ctx.arc(cx, cy, s * 0.7, 0, Math.PI * 2);
        ctx.stroke();
        // Inner circle
        ctx.beginPath();
        ctx.arc(cx, cy, s * 0.28, 0, Math.PI * 2);
        ctx.stroke();
        // Crosshairs
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.moveTo(cx - s * 0.95, cy); ctx.lineTo(cx - s * 0.45, cy);
        ctx.moveTo(cx + s * 0.45, cy); ctx.lineTo(cx + s * 0.95, cy);
        ctx.moveTo(cx, cy - s * 0.95); ctx.lineTo(cx, cy - s * 0.45);
        ctx.moveTo(cx, cy + s * 0.45); ctx.lineTo(cx, cy + s * 0.95);
        ctx.stroke();
        // Center dot
        ctx.fillStyle = dimColor;
        ctx.beginPath();
        ctx.arc(cx, cy, s * 0.12, 0, Math.PI * 2);
        ctx.fill();
        break;
      }

      case 'users': {
        // Two user figures
        ctx.fillStyle = baseColor;
        // Left person (head + body)
        ctx.beginPath(); ctx.arc(cx - s * 0.32, cy - s * 0.2, s * 0.28, 0, Math.PI * 2); ctx.fill();
        ctx.beginPath();
        ctx.ellipse(cx - s * 0.32, cy + s * 0.42, s * 0.34, s * 0.22, 0, Math.PI, 0); ctx.fill();
        // Right person (slightly behind)
        ctx.fillStyle = dimColor;
        ctx.globalAlpha = 0.85;
        ctx.beginPath(); ctx.arc(cx + s * 0.32, cy - s * 0.12, s * 0.26, 0, Math.PI * 2); ctx.fill();
        ctx.beginPath();
        ctx.ellipse(cx + s * 0.32, cy + s * 0.48, s * 0.30, s * 0.20, 0, Math.PI, 0); ctx.fill();
        break;
      }

      case 'swords': {
        // Two crossed swords
        ctx.save();
        ctx.translate(cx, cy);
        ctx.rotate(Math.PI / 4);
        // Sword 1
        ctx.fillStyle = baseColor;
        ctx.fillRect(-s * 0.08, -s * 0.85, s * 0.16, s * 1.4);
        // Guard
        ctx.fillRect(-s * 0.38, -s * 0.05, s * 0.76, s * 0.14);
        // Sword 2 (rotated)
        ctx.rotate(Math.PI / 2);
        ctx.fillStyle = dimColor;
        ctx.fillRect(-s * 0.08, -s * 0.85, s * 0.16, s * 1.4);
        ctx.fillRect(-s * 0.38, -s * 0.05, s * 0.76, s * 0.14);
        ctx.restore();
        break;
      }

      case 'coins': {
        // Stack of coins
        ctx.fillStyle = baseColor;
        // Bottom coin (offset)
        ctx.beginPath();
        ctx.ellipse(cx + s * 0.15, cy + s * 0.18, s * 0.55, s * 0.22, 0, 0, Math.PI * 2);
        ctx.fill();
        // Top coin
        ctx.fillStyle = MC.GOLD_LIGHT;
        ctx.beginPath();
        ctx.ellipse(cx, cy, s * 0.55, s * 0.22, 0, 0, Math.PI * 2);
        ctx.fill();
        // Coin detail ($ symbol hint)
        ctx.fillStyle = dimColor;
        ctx.font = `bold ${Math.floor(s)}px Arial`;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText('$', cx, cy + 1);
        break;
      }

      case 'skin': {
        // Tank/paintbrush icon
        ctx.fillStyle = baseColor;
        // Tank body
        this._roundRect(ctx, cx - s * 0.55, cy - s * 0.15, s * 1.1, s * 0.55, 3);
        ctx.fill();
        // Barrel
        ctx.fillRect(cx + s * 0.2, cy - s * 0.65, s * 0.18, s * 0.52);
        // Wheels hint
        ctx.fillStyle = dimColor;
        ctx.beginPath();
        ctx.arc(cx - s * 0.3, cy + s * 0.4, s * 0.15, 0, Math.PI * 2);
        ctx.fill();
        ctx.beginPath();
        ctx.arc(cx + s * 0.3, cy + s * 0.4, s * 0.15, 0, Math.PI * 2);
        ctx.fill();
        // Star sparkle (skin customization hint)
        ctx.fillStyle = MC.GOLD_LIGHT;
        for (let i = 0; i < 3; i++) {
          const angle = (i / 3) * Math.PI * 2 - Math.PI / 2;
          const sx = cx + Math.cos(angle) * s * 0.7;
          const sy = cy + Math.sin(angle) * s * 0.7 - s * 0.2;
          ctx.beginPath();
          ctx.arc(sx, sy, s * 0.08, 0, Math.PI * 2);
          ctx.fill();
        }
        break;
      }

      case 'ranking': {
        // Podium/ranking icon
        ctx.fillStyle = baseColor;
        // 2nd place (left, shorter)
        ctx.fillRect(cx - s * 0.55, cy, s * 0.4, s * 0.6);
        ctx.fillStyle = '#C0C0C0';
        ctx.fillRect(cx - s * 0.15, cy - s * 0.3, s * 0.4, s * 0.9);
        // 1st place (center, tallest)
        ctx.fillStyle = baseColor;
        ctx.fillRect(cx + s * 0.25, cy + s * 0.15, s * 0.4, s * 0.45);
        // Numbers
        ctx.fillStyle = '#333';
        ctx.font = `bold ${Math.floor(s * 0.3)}px Arial`;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText('2', cx - s * 0.35, cy + s * 0.3);
        ctx.fillText('1', cx + s * 0.05, cy);
        ctx.fillText('3', cx + s * 0.45, cy + s * 0.4);
        break;
      }

      case 'settings': {
        // Gear/cog icon
        ctx.strokeStyle = baseColor;
        ctx.lineWidth = 2.5;
        ctx.beginPath();
        ctx.arc(cx, cy, s * 0.35, 0, Math.PI * 2);
        ctx.stroke();
        // Gear teeth
        ctx.fillStyle = baseColor;
        const teeth = 8;
        for (let i = 0; i < teeth; i++) {
          const angle = (i / teeth) * Math.PI * 2;
          const tx = cx + Math.cos(angle) * s * 0.5;
          const ty = cy + Math.sin(angle) * s * 0.5;
          ctx.beginPath();
          ctx.arc(tx, ty, s * 0.1, 0, Math.PI * 2);
          ctx.fill();
        }
        // Center hole
        ctx.fillStyle = dimColor;
        ctx.beginPath();
        ctx.arc(cx, cy, s * 0.15, 0, Math.PI * 2);
        ctx.fill();
        break;
      }

      case 'shield': {
        // Shield icon (for 3v3 team mode)
        ctx.fillStyle = baseColor;
        ctx.beginPath();
        ctx.moveTo(cx, cy - s * 0.65);
        ctx.lineTo(cx + s * 0.55, cy - s * 0.35);
        ctx.lineTo(cx + s * 0.5, cy + s * 0.45);
        ctx.lineTo(cx, cy + s * 0.6);
        ctx.lineTo(cx - s * 0.5, cy + s * 0.45);
        ctx.lineTo(cx - s * 0.55, cy - s * 0.35);
        ctx.closePath();
        ctx.fill();

        // Inner detail
        ctx.strokeStyle = dimColor;
        ctx.lineWidth = 1;
        const shieldInner = 0.7;
        ctx.beginPath();
        ctx.moveTo(cx, cy - s * 0.65 * shieldInner);
        ctx.lineTo(cx + s * 0.55 * shieldInner, cy - s * 0.35 * shieldInner);
        ctx.lineTo(cx + s * 0.5 * shieldInner, cy + s * 0.45 * shieldInner);
        ctx.lineTo(cx, cy + s * 0.6 * shieldInner);
        ctx.lineTo(cx - s * 0.5 * shieldInner, cy + s * 0.45 * shieldInner);
        ctx.lineTo(cx - s * 0.55 * shieldInner, cy - s * 0.35 * shieldInner);
        ctx.closePath();
        ctx.stroke();

        // "3V3" text inside
        ctx.fillStyle = dimColor;
        ctx.font = `bold ${Math.max(6, s * 0.32)}px Arial`;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText('3v3', cx, cy + s * 0.08);
        break;
      }

      default:
        // Fallback circle icon
        ctx.fillStyle = baseColor;
        ctx.beginPath();
        ctx.arc(cx, cy, s * 0.5, 0, Math.PI * 2);
        ctx.fill();
    }

    ctx.restore();
  },

  /**
   * Utility bar button — horizontal layout (icon on left, text on right).
   * Used for the 4-column bottom utility bar.
   */
  _drawUtilButton(ctx, btn, label, subtitle, isPressed, customBg, iconType) {
    const r = 8;
    ctx.save();
    ctx.globalAlpha = 0.85;

    const iconSz = Math.min(24, btn.h * 0.48);
    const innerPad = Math.max(8, btn.w * 0.06);

    // Shadow
    ctx.fillStyle = 'rgba(0,0,0,0.25)';
    this._roundRect(ctx, btn.x + 1, btn.y + 2, btn.w, btn.h, r);
    ctx.fill();

    // Body gradient
    const bgGrad = ctx.createLinearGradient(btn.x, btn.y, btn.x, btn.y + btn.h);
    if (isPressed) {
      bgGrad.addColorStop(0, '#243a5c');
      bgGrad.addColorStop(1, '#1a2d4a');
    } else if (customBg) {
      bgGrad.addColorStop(0, customBg);
      bgGrad.addColorStop(1, this._darkenColor(customBg, 12));
    } else {
      bgGrad.addColorStop(0, '#182844');
      bgGrad.addColorStop(1, '#121d33');
    }
    ctx.fillStyle = bgGrad;
    ctx.strokeStyle = isPressed ? MC.GOLD : 'rgba(50,90,140,0.5)';
    ctx.lineWidth = 1;
    this._roundRect(ctx, btn.x, btn.y, btn.w, btn.h, r);
    ctx.fill();
    ctx.stroke();

    // Icon on the left side
    if (iconType) {
      const ix = btn.x + innerPad;
      const iy = btn.y + (btn.h - iconSz) / 2;
      this._drawButtonIcon(ctx, ix, iy, iconSz, iconType, isPressed);
    }

    // Text to the right of icon — match right-panel mode button font size
    const txtX = btn.x + innerPad + iconSz + 6;
    const maxTxtW = btn.x + btn.w - innerPad - txtX;
    // Match mode button primary text size: bold max(15, h*0.32)
    const txtFont = `bold ${Math.max(14, btn.h * 0.30)}px Arial`;
    ctx.fillStyle = isPressed ? MC.GOLD_LIGHT : MC.BTN_TEXT_PRIMARY;
    ctx.font = txtFont;
    ctx.textAlign = 'left';
    ctx.textBaseline = 'middle';

    // Truncate long text to fit remaining width
    let displayLabel = label;
    while (ctx.measureText(displayLabel).width > maxTxtW && displayLabel.length > 3) {
      displayLabel = displayLabel.slice(0, -2) + '…';
    }
    ctx.fillText(displayLabel, txtX, btn.y + btn.h / 2);

    ctx.restore();
  },

  /** Darken a hex color by a percentage */
  _darkenColor(hex, percent) {
    const num = parseInt(hex.replace('#', ''), 16);
    const amt = Math.round(2.55 * percent);
    const R = Math.max((num >> 16) - amt, 0);
    const G = Math.max(((num >> 8) & 0x00FF) - amt, 0);
    const B = Math.max((num & 0x0000FF) - amt, 0);
    return '#' + (0x1000000 + R * 0x10000 + G * 0x100 + B).toString(16).slice(1);
  },

  // ---- Tank Icon ----
  _drawTankIcon(ctx, cx, cy) {
    const bounce = Math.sin(this._tankAnim * 3) * 1.5;
    const pulse  = 0.5 + 0.5 * Math.sin(this._tankAnim * 2);
    const s = 13; // body half-size (compact: 26×26)

    ctx.save();
    ctx.translate(cx, cy + bounce);

    // ── 1. OUTER GLOW HALO (breathing golden aura) ──
    ctx.save();
    ctx.globalAlpha = 0.15 + pulse * 0.12;
    ctx.fillStyle = MC.GOLD;
    ctx.beginPath();
    ctx.arc(0, 0, s * 1.55, 0, Math.PI * 2);
    ctx.fill();
    ctx.restore();

    // ── 2. GROUND SHADOW (soft ellipse underneath) ──
    ctx.save();
    ctx.globalAlpha = 0.35;
    ctx.fillStyle = '#000';
    ctx.beginPath();
    ctx.ellipse(0, s + 6, s * 1.1, 3, 0, 0, Math.PI * 2);
    ctx.fill();
    ctx.restore();

    // ── 3. TRACKS (left & right, with segment pattern) ──
    const trackW = 5;
    const trackX = s;
    // Left track
    ctx.fillStyle = '#4A3508';
    this._roundRect(ctx, -trackX - trackW, -s, trackW, s * 2, 1.5);
    ctx.fill();
    // Right track
    this._roundRect(ctx, trackX, -s, trackW, s * 2, 1.5);
    ctx.fill();
    // Track top highlight
    ctx.fillStyle = 'rgba(255, 220, 120, 0.35)';
    ctx.fillRect(-trackX - trackW + 0.8, -s + 0.8, trackW - 1.6, 1);
    ctx.fillRect(trackX + 0.8, -s + 0.8, trackW - 1.6, 1);
    // Track segment lines (metallic plate pattern)
    ctx.strokeStyle = 'rgba(0, 0, 0, 0.55)';
    ctx.lineWidth = 0.8;
    for (let ty = -s + 4; ty < s - 1; ty += 4) {
      ctx.beginPath();
      ctx.moveTo(-trackX - trackW, ty);
      ctx.lineTo(-trackX, ty);
      ctx.stroke();
      ctx.beginPath();
      ctx.moveTo(trackX, ty);
      ctx.lineTo(trackX + trackW, ty);
      ctx.stroke();
    }

    // ── 4. BODY (square, with vertical metallic gradient) ──
    ctx.save();
    ctx.shadowColor = MC.GOLD;
    ctx.shadowBlur = 12;
    const bodyGrad = ctx.createLinearGradient(0, -s, 0, s);
    bodyGrad.addColorStop(0,   '#FFF3A8');   // top highlight
    bodyGrad.addColorStop(0.3, MC.GOLD);      // main gold
    bodyGrad.addColorStop(0.75, '#C89A1C');
    bodyGrad.addColorStop(1,   '#7A5A0A');   // bottom shadow
    ctx.fillStyle = bodyGrad;
    this._roundRect(ctx, -s, -s, s * 2, s * 2, 3);
    ctx.fill();
    ctx.restore();

    // ── 5. BODY EDGE OUTLINE ──
    ctx.strokeStyle = 'rgba(255, 235, 150, 0.7)';
    ctx.lineWidth = 1;
    this._roundRect(ctx, -s, -s, s * 2, s * 2, 3);
    ctx.stroke();

    // ── 6. TOP HIGHLIGHT STRIP (bright metallic sheen) ──
    ctx.fillStyle = 'rgba(255, 255, 255, 0.35)';
    this._roundRect(ctx, -s + 2, -s + 2, s * 2 - 4, 3, 1.5);
    ctx.fill();

    // ── 7. ARMOR PLATE DETAIL (X-cross rivets in 4 corners + center crosshair) ──
    const rivetOffset = s * 0.6;
    ctx.fillStyle = '#6B4A08';
    for (const [rx, ry] of [[-rivetOffset, -rivetOffset], [rivetOffset, -rivetOffset],
                             [-rivetOffset, rivetOffset], [rivetOffset, rivetOffset]]) {
      ctx.beginPath();
      ctx.arc(rx, ry, 1.4, 0, Math.PI * 2);
      ctx.fill();
      // Tiny rivet highlight
      ctx.fillStyle = 'rgba(255, 240, 180, 0.8)';
      ctx.beginPath();
      ctx.arc(rx - 0.3, ry - 0.3, 0.5, 0, Math.PI * 2);
      ctx.fill();
      ctx.fillStyle = '#6B4A08';
    }

    // ── 8. TURRET (diamond-shaped center cap with gradient) ──
    const turretR = s * 0.42;
    ctx.save();
    ctx.shadowColor = MC.GOLD;
    ctx.shadowBlur = 6;
    const turretGrad = ctx.createRadialGradient(-turretR * 0.3, -turretR * 0.3, 0, 0, 0, turretR);
    turretGrad.addColorStop(0,   '#FFF3A8');
    turretGrad.addColorStop(0.5, '#E0B020');
    turretGrad.addColorStop(1,   '#8B6914');
    ctx.fillStyle = turretGrad;
    // Diamond (rotated square) for "military hatch" feel
    ctx.beginPath();
    ctx.moveTo(0, -turretR);
    ctx.lineTo(turretR, 0);
    ctx.lineTo(0, turretR);
    ctx.lineTo(-turretR, 0);
    ctx.closePath();
    ctx.fill();
    ctx.restore();

    // Turret edge
    ctx.strokeStyle = 'rgba(255, 235, 150, 0.8)';
    ctx.lineWidth = 0.8;
    ctx.beginPath();
    ctx.moveTo(0, -turretR);
    ctx.lineTo(turretR, 0);
    ctx.lineTo(0, turretR);
    ctx.lineTo(-turretR, 0);
    ctx.closePath();
    ctx.stroke();

    // Turret internal cross
    ctx.strokeStyle = 'rgba(0, 0, 0, 0.35)';
    ctx.lineWidth = 0.6;
    ctx.beginPath();
    ctx.moveTo(0, -turretR); ctx.lineTo(0, turretR);
    ctx.stroke();
    ctx.beginPath();
    ctx.moveTo(-turretR, 0); ctx.lineTo(turretR, 0);
    ctx.stroke();

    // Turret center hatch
    ctx.fillStyle = '#FFF3A8';
    ctx.beginPath();
    ctx.arc(0, 0, 2.5, 0, Math.PI * 2);
    ctx.fill();

    // ── 9. BARREL (thick, with metallic gradient) ──
    const barrelW = 6;
    const barrelH = 16;
    const barrelY = -s - barrelH;
    ctx.save();
    const barrelGrad = ctx.createLinearGradient(-barrelW / 2, 0, barrelW / 2, 0);
    barrelGrad.addColorStop(0,   '#6B4A08');
    barrelGrad.addColorStop(0.3, '#B8860B');
    barrelGrad.addColorStop(0.5, '#FFF3A8');
    barrelGrad.addColorStop(0.7, '#B8860B');
    barrelGrad.addColorStop(1,   '#6B4A08');
    ctx.fillStyle = barrelGrad;
    this._roundRect(ctx, -barrelW / 2, barrelY, barrelW, barrelH, 1.5);
    ctx.fill();
    ctx.restore();
    // Barrel outline
    ctx.strokeStyle = 'rgba(255, 235, 150, 0.55)';
    ctx.lineWidth = 0.6;
    this._roundRect(ctx, -barrelW / 2, barrelY, barrelW, barrelH, 1.5);
    ctx.stroke();

    // ── 10. MUZZLE TIP (flared end with glow) ──
    ctx.save();
    ctx.shadowColor = '#FFF3A8';
    ctx.shadowBlur = 5 + pulse * 3;
    ctx.fillStyle = '#2A1D05';
    this._roundRect(ctx, -barrelW / 2 - 1, barrelY - 2, barrelW + 2, 3, 1);
    ctx.fill();
    ctx.restore();
    // Muzzle inner bright dot
    ctx.fillStyle = `rgba(255, 240, 150, ${0.6 + pulse * 0.4})`;
    ctx.beginPath();
    ctx.arc(0, barrelY - 0.5, 1, 0, Math.PI * 2);
    ctx.fill();

    // ── 11. HEADLIGHTS (front of tank — 2 small glowing dots) ──
    ctx.fillStyle = `rgba(255, 255, 200, ${0.7 + pulse * 0.3})`;
    ctx.shadowColor = '#FFF3A8';
    ctx.shadowBlur = 4;
    ctx.beginPath();
    ctx.arc(-s * 0.55, -s + 2.5, 1.3, 0, Math.PI * 2);
    ctx.fill();
    ctx.beginPath();
    ctx.arc(s * 0.55, -s + 2.5, 1.3, 0, Math.PI * 2);
    ctx.fill();
    ctx.shadowBlur = 0;

    ctx.restore();
  },

  // ---- Utility ----
  _roundRect(ctx, x, y, w, h, r) {
    ctx.beginPath();
    ctx.moveTo(x + r, y);
    ctx.lineTo(x + w - r, y);
    ctx.arcTo(x + w, y, x + w, y + r, r);
    ctx.lineTo(x + w, y + h - r);
    ctx.arcTo(x + w, y + h, x + w - r, y + h, r);
    ctx.lineTo(x + r, y + h);
    ctx.arcTo(x, y + h, x, y + h - r, r);
    ctx.lineTo(x, y + r);
    ctx.arcTo(x, y, x + r, y, r);
    ctx.closePath();
  },

  // ============================================================
  // Player Profile (nickname acquisition)
  // ============================================================

  /**
   * Load avatar image from URL for Canvas rendering.
   * @param {string} url
   * @private
   */
  /**
   * Load background image from local path.
   * @private
   */
  _loadBgImage() {
    if (this._bgImage) return;
    try {
      const img = wx.createImage();
      img.onload = () => {
        this._bgImage = img;
        console.log('[MenuScene] Background image loaded:', img.width, 'x', img.height);
      };
      img.onerror = (e) => {
        console.warn('[MenuScene] Failed to load background image, using gradient fallback');
      };
      img.src = 'js/ui/images/bg.png';
    } catch (e) {
      console.warn('[MenuScene] _loadBgImage error:', e && e.message);
    }
  },

  _loadAvatarImage(url) {
    if (!url || this._avatarImg) return;
    try {
      const img = wx.createImage();
      img.onload = () => {
        this._avatarImg = img;
      };
      img.onerror = () => {
        console.warn('[MenuScene] Failed to load avatar image');
      };
      img.src = url;
    } catch (e) {
      console.warn('[MenuScene] _loadAvatarImage error:', e && e.message);
    }
  },

  /**
   * Kick off profile acquisition on menu enter.
   *
   * Since WeChat 2022-10, `wx.getUserInfo` returns "scope unauthorized" —
   * the ONLY way to get the real nickname + avatar is `wx.createUserInfoButton`.
   * We create a transparent overlay button that covers the avatar area in the
   * top-left corner. When the user taps their avatar, WeChat returns the real
   * profile data.
   * @private
   */
  _initPlayerProfile() {
    const profile = GameGlobal.playerProfile;
    if (!profile) return;

    // If already granted (from a previous session's cache), no button needed
    if (profile.granted) return;

    // Layout must match the avatar area drawn in render():
    //   avatarX=10, avatarY=10, avatarSize=28 + nickname text area
    const avatarLayout = {
      x: 8,
      y: 8,
      width: 120,
      height: 32,
    };

    // Create the UserInfoButton — visible style covering avatar + nickname area
    if (typeof profile.fetchSilent === 'function') {
      profile.fetchSilent(avatarLayout).then((ok) => {
        console.log('[MenuScene] fetchSilent completed, granted=', ok);
        if (ok) {
          // Button was tapped and profile was granted — destroy it
          profile.destroyUserInfoButton();
        }
      }).catch((e) => {
        console.warn('[MenuScene] fetchSilent error:', e);
      });
    }
  },

  // ============================================================
  // Touch
  // ============================================================
  handleTouch(eventType, e) {
    if (eventType === 'touchstart') {
      const touch = e.touches[0];
      const tx = touch.clientX;
      const ty = touch.clientY;

      for (let i = 0; i < buttonRects.length; i++) {
        const btn = buttonRects[i];
        if (tx >= btn.x && tx <= btn.x + btn.w && ty >= btn.y && ty <= btn.y + btn.h) {
          this._pressedIndex = i;
          break;
        }
      }
    } else if (eventType === 'touchend') {
      if (this._pressedIndex >= 0) {
        const btn = buttonRects[this._pressedIndex];
        this._pressedIndex = -1;

        const sm = GameGlobal.sceneManager;
        if (btn.scene === SCENE.GAME) {
          if (!sm._scenes.has(SCENE.BUFF_SELECT)) {
            const BuffSelectScene = require('./BuffSelectScene');
            sm.register(SCENE.BUFF_SELECT, BuffSelectScene);
          }
          sm.switchTo(SCENE.BUFF_SELECT, { mode: btn.mode });
        } else if (btn.scene === 'DAILY_GOLD') {
          const adm = GameGlobal.adManager;
          if (adm && adm.getDailyGoldRemaining() > 0) {
            adm.showDailyGoldAd((completed) => {
              if (completed) {
                try {
                  wx.showToast({ title: t('dailyGold.reward') || '+100 Gold!', icon: 'none', duration: 1500 });
                } catch (e) {}
              }
            });
          }
        } else if (btn.scene === SCENE.SHOP) {
          if (!sm._scenes.has(SCENE.SHOP)) {
            const ShopScene = require('./ShopScene');
            sm.register(SCENE.SHOP, ShopScene);
          }
          sm.switchTo(SCENE.SHOP);
        } else if (btn.scene === SCENE.SKIN) {
          if (!sm._scenes.has(SCENE.SKIN)) {
            const SkinScene = require('./SkinScene');
            sm.register(SCENE.SKIN, SkinScene);
          }
          sm.switchTo(SCENE.SKIN);
        } else if (btn.scene === SCENE.SETTINGS) {
          if (!sm._scenes.has(SCENE.SETTINGS)) {
            const SettingsScene = require('./SettingsScene');
            sm.register(SCENE.SETTINGS, SettingsScene);
          }
          sm.switchTo(SCENE.SETTINGS);
        } else if (btn.scene === SCENE.RANKING) {
          if (!sm._scenes.has(SCENE.RANKING)) {
            const RankingScene = require('./RankingScene');
            sm.register(SCENE.RANKING, RankingScene);
          }
          sm.switchTo(SCENE.RANKING);
        } else if (btn.scene === SCENE.PVP_ROOM) {
          if (!sm._scenes.has(SCENE.PVP_ROOM)) {
            const RoomScene = require('./RoomScene');
            sm.register(SCENE.PVP_ROOM, RoomScene);
          }
          sm.switchTo(SCENE.PVP_ROOM);
        } else if (btn.scene === SCENE.TEAM_2V2_ROOM) {
          if (!sm._scenes.has(SCENE.TEAM_2V2_ROOM)) {
            const Team2v2RoomScene = require('./Team2v2RoomScene');
            sm.register(SCENE.TEAM_2V2_ROOM, Team2v2RoomScene);
          }
          sm.switchTo(SCENE.TEAM_2V2_ROOM);
        } else if (btn.scene === SCENE.TEAM_ROOM) {
          if (!sm._scenes.has(SCENE.TEAM_ROOM)) {
            const TeamRoomScene = require('./TeamRoomScene');
            sm.register(SCENE.TEAM_ROOM, TeamRoomScene);
          }
          sm.switchTo(SCENE.TEAM_ROOM);
        }
      }
    }
  },
};

module.exports = MenuScene;
