/**
 * GameScene.js
 * Main battle scene - orchestrates map, tanks, bullets, power-ups, and HUD.
 * This is the core gameplay scene that integrates all sub-systems.
 */

const {
  SCREEN_WIDTH,
  SCREEN_HEIGHT,
  COLORS,
  SCENE,
  GAME_MODE,
  MAP_OFFSET_X,
  MAP_OFFSET_Y,
  MAP_WIDTH,
  MAP_HEIGHT,
  TILE_SIZE,
  GRID_COLS,
  GRID_ROWS,
  DIRECTION,
  DIR_VECTORS,
  BULLET_SPEED,
  FIRE_LEVEL,
  POWERUP_TYPE,
  FREEZE_DURATION,
  SHIELD_DURATION,
  SHOVEL_DURATION,
  TANK_TYPE,
  TERRAIN,
} = require('../base/GameGlobal');

const ObjectPool = require('../base/ObjectPool');
const MapManager = require('../managers/MapManager');
const CollisionManager = require('../managers/CollisionManager');
const SpawnManager = require('../managers/SpawnManager');
const PlayerTank = require('../entities/PlayerTank');
const Bullet = require('../entities/Bullet');
const Explosion = require('../entities/Explosion');
const PowerUp = require('../entities/PowerUp');
const Joystick = require('../ui/Joystick');
const FireButton = require('../ui/FireButton');
const { getLevelData } = require('../data/LevelData');
const { t } = require('../i18n/I18n');

const GameScene = {
  _mode: GAME_MODE.CLASSIC,
  _level: 1,
  _initialized: false,
  _gameOver: false,
  _victory: false,
  _paused: false,

  // Sub-systems
  _mapManager: null,
  _collisionManager: null,
  _spawnManager: null,
  _playerTank: null,
  _joystick: null,
  _fireButton: null,

  // Entity lists
  _enemies: [],
  _bullets: [],
  _explosions: [],
  _powerUps: [],

  // Object pools
  _bulletPool: null,
  _explosionPool: null,

  // Game stats
  _stats: null,
  _levelStartTime: 0,
  _freezeTimer: 0,

  // Game over delay
  _gameOverDelay: 0,
  _gameOverDelayDuration: 2, // seconds

  // Revive ad state
  _reviveAdUsed: false,
  _reviveCount: 0, // Track revive count for escalating cost
  _showingReviveDialog: false,
  _reviveDialogButtons: null,

  // Buff manager reference
  _buffManager: null,



  enter(params) {
    this._mode = (params && params.mode) || GAME_MODE.CLASSIC;
    this._level = (params && params.level) || 1;
    this._gameOver = false;
    this._victory = false;
    this._paused = false;
    this._freezeTimer = 0;
    this._gameOverDelay = 0;
    this._cachedBasePos = null;
    this._reviveAdUsed = false;
    this._reviveCount = 0;
    this._showingReviveDialog = false;
    this._reviveDialogButtons = null;

    // Initialize buff manager reference
    this._buffManager = GameGlobal.buffManager || null;

    // Initialize stats
    this._stats = {
      kills: { normal: 0, fast: 0, armor: 0, boss: 0 },
      totalKills: 0,
      score: 0,
      timeElapsed: 0,
      baseAlive: true,
    };

    // Initialize object pools
    this._bulletPool = new ObjectPool(() => new Bullet(), null, 20);
    this._explosionPool = new ObjectPool(() => new Explosion(), null, 10);

    // Initialize entity lists
    this._enemies = [];
    this._bullets = [];
    this._explosions = [];
    this._powerUps = [];

    // Initialize map
    this._mapManager = new MapManager();
    const levelData = getLevelData(this._level);
    this._mapManager.loadGrid(levelData.grid);

    // Initialize spawn manager
    this._spawnManager = new SpawnManager();
    this._spawnManager.init(levelData);

    // Initialize player
    this._playerTank = new PlayerTank({
      col: levelData.playerSpawn.col,
      row: levelData.playerSpawn.row,
    });
    this._playerTank.activateShield(3000); // spawn protection

    // Apply equipped skin — only non-default skins override tank color
    if (GameGlobal.skinManager) {
      const skinId = GameGlobal.skinManager.getEquippedSkinId();
      if (skinId && skinId !== 'default') {
        this._playerTank._skinColors = GameGlobal.skinManager.getCurrentSkinColors();
        this._playerTank._skinId = skinId;
      }
    }

    // Safety: ensure player spawn area is clear of blocking terrain
    this._clearSpawnArea(levelData.playerSpawn.col, levelData.playerSpawn.row);

    // Initialize collision manager
    this._collisionManager = new CollisionManager({
      mapManager: this._mapManager,
      onExplosion: (x, y, isBig) => this._spawnExplosion(x, y, isBig),
      eventBus: GameGlobal.eventBus,
    });

    // Initialize controls
    this._joystick = new Joystick();
    this._fireButton = new FireButton();
    this._fireButton.onFire(() => this._playerFire());

    // Event listeners
    this._setupEvents();

    this._levelStartTime = Date.now();
    this._initialized = true;

    // Activate pre-game buffs if any were purchased
    if (this._buffManager) {
      this._buffManager.activateBuffs(this._playerTank);
    }

    // Preload rewarded video ad for revive/double reward scenes
    if (GameGlobal.adManager) {
      GameGlobal.adManager.preloadRewardedVideo();
    }

    console.log(`[GameScene] Level ${this._level} started. Mode: ${this._mode}`);
  },

  exit() {
    this._initialized = false;
    this._cleanupEvents();
    this._bullets = [];
    this._enemies = [];
    this._explosions = [];
    this._powerUps = [];

    // Clear buffs at end of round
    if (this._buffManager) {
      this._buffManager.clearBuffs();
    }
  },

  _setupEvents() {
    const eb = GameGlobal.eventBus;
    this._onEnemyDestroyed = (data) => this._handleEnemyDestroyed(data);
    this._onPlayerDestroyed = () => this._handlePlayerDestroyed();
    this._onBaseDestroyed = () => this._handleBaseDestroyed();

    eb.on('enemy:destroyed', this._onEnemyDestroyed);
    eb.on('player:destroyed', this._onPlayerDestroyed);
    eb.on('base:destroyed', this._onBaseDestroyed);
  },

  _cleanupEvents() {
    const eb = GameGlobal.eventBus;
    eb.off('enemy:destroyed', this._onEnemyDestroyed);
    eb.off('player:destroyed', this._onPlayerDestroyed);
    eb.off('base:destroyed', this._onBaseDestroyed);
  },

  // ============================================================
  // Update
  // ============================================================
  update(dt) {
    if (!this._initialized || this._paused) return;

    // Game over delay (show explosion before transitioning)
    if (this._gameOver || this._victory) {
      this._gameOverDelay += dt;
      // Still update explosions during delay
      this._updateExplosions(dt);
      if (this._gameOverDelay >= this._gameOverDelayDuration) {
        this._transitionToResult();
      }
      return;
    }

    this._stats.timeElapsed += dt;

    // Update map (shovel timer etc.)
    this._mapManager.update(dt);

    // Update freeze timer
    if (this._freezeTimer > 0) {
      this._freezeTimer -= dt * 1000;
      if (this._freezeTimer < 0) this._freezeTimer = 0;
    }

    // Player movement
    if (this._playerTank.alive && this._joystick.active && this._joystick.direction >= 0) {
      this._playerTank.move(this._joystick.direction, dt, this._mapManager);
    }
    this._playerTank.update(dt);

    // Update buff timers
    if (this._buffManager) {
      this._buffManager.update(dt, this._playerTank);
    }

    // Spawn enemies (pause spawning while freeze is active)
    if (this._freezeTimer <= 0) {
      const newEnemy = this._spawnManager.update(dt, this._enemies);
      if (newEnemy) {
        this._enemies.push(newEnemy);
      }
    }

    // Update enemies — find base position from the grid
    const basePos = this._findBasePos();
    for (const enemy of this._enemies) {
      if (this._freezeTimer > 0) {
        enemy.frozen = true;
      } else {
        enemy.frozen = false;
      }
      enemy.update(dt, this._mapManager, basePos, (tank) => this._enemyFire(tank));
    }

    // Update bullets (freeze enemy bullets while freeze is active)
    for (const bullet of this._bullets) {
      if (this._freezeTimer > 0 && bullet.owner === 'enemy') {
        continue; // enemy bullets are frozen
      }
      bullet.update(dt);
    }

    // Update power-ups
    for (const pu of this._powerUps) {
      pu.update(dt);
    }

    // Collision detection
    this._collisionManager.update({
      player: this._playerTank,
      enemies: this._enemies,
      bullets: this._bullets,
    });

    // Check power-up pickup
    this._checkPowerUpPickup();

    // Update explosions
    this._updateExplosions(dt);

    // Cleanup dead entities
    this._cleanup();

    // Check victory condition
    this._checkVictory();
  },

  // ============================================================
  // Render
  // ============================================================
  render(ctx) {
    if (!this._initialized) return;

    // Draw game area background
    ctx.fillStyle = '#111111';
    ctx.fillRect(MAP_OFFSET_X, MAP_OFFSET_Y, MAP_WIDTH, MAP_HEIGHT);

    // Render map (terrain layer)
    this._mapManager.render(ctx);

    // Render power-ups
    for (const pu of this._powerUps) {
      pu.render(ctx);
    }

    // Render player
    this._playerTank.render(ctx);

    // Render enemies
    for (const enemy of this._enemies) {
      enemy.render(ctx);
    }

    // Render forest overlay (on top of tanks)
    this._mapManager.renderForestOverlay(ctx);

    // Render bullets
    for (const bullet of this._bullets) {
      bullet.render(ctx);
    }

    // Render explosions
    for (const exp of this._explosions) {
      exp.render(ctx);
    }

    // Render HUD
    this._renderHUD(ctx);

    // Render controls
    this._joystick.render(ctx);
    this._fireButton.render(ctx);

    // Render pause overlay
    if (this._paused && !this._showingReviveDialog) {
      this._renderPauseOverlay(ctx);
    }

    // Render revive ad dialog
    if (this._showingReviveDialog) {
      this._renderReviveDialog(ctx);
    }

    // Game over text
    if (this._gameOver) {
      this._renderGameOverText(ctx, t('game.gameOver'));
    } else if (this._victory) {
      this._renderGameOverText(ctx, t('game.stageClear'));
    }
  },

  // ============================================================
  // HUD Rendering
  // ============================================================
  _renderHUD(ctx) {
    // In landscape mode, HUD is rendered on the sides of the map
    const leftX = MAP_OFFSET_X - 8; // right edge of left panel
    const rightX = MAP_OFFSET_X + MAP_WIDTH + 8; // left edge of right panel
    const topY = MAP_OFFSET_Y + 10;

    // === Left side panel ===
    ctx.fillStyle = COLORS.HUD_TEXT;
    ctx.font = 'bold 12px Arial';
    ctx.textAlign = 'right';
    ctx.textBaseline = 'top';

    // Level info
    ctx.fillText(t('game.level', { level: this._level }), leftX, topY);

    // Player lives
    ctx.fillStyle = '#FFD700';
    ctx.font = '11px Arial';
    ctx.fillText(t('game.hp', { count: this._playerTank.lives }), leftX, topY + 20);

    // Fire level
    ctx.fillText(t('game.fireLevel', { level: this._playerTank.fireLevel }), leftX, topY + 38);

    // === Right side panel ===
    ctx.textAlign = 'left';
    ctx.textBaseline = 'top';

    // Remaining enemies
    ctx.fillStyle = COLORS.HUD_TEXT;
    ctx.font = 'bold 12px Arial';
    const aliveEnemies = this._enemies.filter((e) => e.alive).length;
    const remaining = this._spawnManager.remainingToSpawn + aliveEnemies;
    ctx.fillText(t('game.enemies', { count: remaining }), rightX, topY);

    // Score
    ctx.fillStyle = '#FFD700';
    ctx.font = '11px Arial';
    ctx.fillText(t('game.score', { score: this._stats.score }), rightX, topY + 20);
  },

  _renderPauseOverlay(ctx) {
    ctx.fillStyle = 'rgba(0,0,0,0.6)';
    ctx.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

    ctx.fillStyle = '#FFFFFF';
    ctx.font = 'bold 28px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(t('common.paused'), SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 - 40);

    ctx.font = '16px Arial';
    ctx.fillText(t('common.tapContinue'), SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 + 10);
  },

  _renderGameOverText(ctx, text) {
    ctx.fillStyle = 'rgba(0,0,0,0.5)';
    ctx.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

    ctx.fillStyle = text === t('game.gameOver') ? '#FF0000' : '#00FF00';
    ctx.font = 'bold 32px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(text, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
  },

  /**
   * Render the revive dialog overlay with dual options (ad + gold).
   * @private
   */
  _renderReviveDialog(ctx) {
    const cx = SCREEN_WIDTH / 2;
    const cy = SCREEN_HEIGHT / 2;

    // Dim background
    ctx.fillStyle = 'rgba(0,0,0,0.7)';
    ctx.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

    // Dialog box
    const boxW = 300;
    const boxH = 180;
    ctx.fillStyle = 'rgba(30,30,30,0.95)';
    ctx.strokeStyle = '#FFD700';
    ctx.lineWidth = 2;
    ctx.fillRect(cx - boxW / 2, cy - boxH / 2, boxW, boxH);
    ctx.strokeRect(cx - boxW / 2, cy - boxH / 2, boxW, boxH);

    // Title text
    ctx.fillStyle = '#FFFFFF';
    ctx.font = 'bold 18px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(t('ad.reviveTitle') || 'Revive Chance', cx, cy - 55);

    // Subtitle
    ctx.fillStyle = '#AAAAAA';
    ctx.font = '12px Arial';
    ctx.fillText(t('ad.reviveDesc') || 'Choose how to revive and continue', cx, cy - 35);

    const btns = this._reviveDialogButtons;
    if (btns) {
      // Watch Ad button (green) - only show if ad is available
      if (btns.watchAd) {
        ctx.fillStyle = '#4CAF50';
        ctx.fillRect(btns.watchAd.x, btns.watchAd.y, btns.watchAd.w, btns.watchAd.h);
        ctx.fillStyle = '#FFFFFF';
        ctx.font = 'bold 13px Arial';
        ctx.fillText(t('ad.watchAd') || '📺 Watch Ad (Free)', btns.watchAd.x + btns.watchAd.w / 2, btns.watchAd.y + btns.watchAd.h / 2);
      }

      // Gold Revive button (orange) - show escalating cost
      if (btns.goldRevive) {
        const reviveCost = this._getReviveCost();
        const hasGold = GameGlobal.currencyManager && GameGlobal.currencyManager.hasGold(reviveCost);
        ctx.fillStyle = hasGold ? '#FF9800' : '#555555';
        ctx.fillRect(btns.goldRevive.x, btns.goldRevive.y, btns.goldRevive.w, btns.goldRevive.h);
        ctx.fillStyle = '#FFFFFF';
        ctx.font = 'bold 13px Arial';
        ctx.fillText(`🪙 ${t('ad.goldRevive') || 'Gold Revive'} (${reviveCost})`, btns.goldRevive.x + btns.goldRevive.w / 2, btns.goldRevive.y + btns.goldRevive.h / 2);
      }

      // Give Up button (gray)
      ctx.fillStyle = '#666666';
      ctx.fillRect(btns.giveUp.x, btns.giveUp.y, btns.giveUp.w, btns.giveUp.h);
      ctx.fillStyle = '#FFFFFF';
      ctx.font = 'bold 13px Arial';
      ctx.fillText(t('ad.giveUp') || 'Give Up', btns.giveUp.x + btns.giveUp.w / 2, btns.giveUp.y + btns.giveUp.h / 2);
    }
  },

  // ============================================================
  // Game Logic
  // ============================================================
  _playerFire() {
    if (!this._playerTank.alive || !this._playerTank.canFire()) return;
    if (this._gameOver || this._victory || this._paused) return;

    const tank = this._playerTank;
    const vec = DIR_VECTORS[tank.direction];
    const bullet = this._bulletPool.get();
    bullet.init({
      x: tank.x + vec.dx * tank.halfSize,
      y: tank.y + vec.dy * tank.halfSize,
      direction: tank.direction,
      owner: 'player',
      canBreakSteel: tank.canBreakSteel(),
      ownerTank: tank,
    });
    tank.activeBullets++;
    this._bullets.push(bullet);
    GameGlobal.audioManager.playSFX('shoot');
  },

  _enemyFire(enemyTank) {
    if (!enemyTank.alive || !enemyTank.canFire()) return;

    const vec = DIR_VECTORS[enemyTank.direction];
    const bullet = this._bulletPool.get();
    bullet.init({
      x: enemyTank.x + vec.dx * enemyTank.halfSize,
      y: enemyTank.y + vec.dy * enemyTank.halfSize,
      direction: enemyTank.direction,
      owner: 'enemy',
      canBreakSteel: false,
      ownerTank: enemyTank,
    });
    enemyTank.activeBullets++;
    this._bullets.push(bullet);
    GameGlobal.audioManager.playSFX('shoot');
  },

  _spawnExplosion(x, y, isBig) {
    const exp = this._explosionPool.get();
    exp.init(x, y, isBig);
    this._explosions.push(exp);
    GameGlobal.audioManager.playSFX(isBig ? 'explosion_big' : 'explosion_small');
  },

  /**
   * Clear any blocking terrain at the player spawn area.
   * Ensures the tank won't be stuck inside walls on spawn.
   * @private
   */
  _clearSpawnArea(col, row) {
    const terrain = this._mapManager.getTerrain(row, col);
    if (terrain !== TERRAIN.EMPTY && terrain !== TERRAIN.FOREST) {
      this._mapManager.setTerrain(row, col, TERRAIN.EMPTY);
    }
  },

  /**
   * Find the base (eagle) position from the map grid.
   * Scans for TERRAIN.BASE and returns its pixel center.
   * Result is cached after first call per level.
   * @private
   * @returns {{x: number, y: number}}
   */
  _findBasePos() {
    if (this._cachedBasePos) return this._cachedBasePos;
    // Scan grid for BASE terrain
    for (let r = GRID_ROWS - 1; r >= 0; r--) {
      for (let c = 0; c < GRID_COLS; c++) {
        if (this._mapManager.getTerrain(r, c) === TERRAIN.BASE) {
          this._cachedBasePos = {
            x: MAP_OFFSET_X + c * TILE_SIZE + TILE_SIZE / 2,
            y: MAP_OFFSET_Y + r * TILE_SIZE + TILE_SIZE / 2,
          };
          return this._cachedBasePos;
        }
      }
    }
    // Fallback: center-bottom
    this._cachedBasePos = {
      x: MAP_OFFSET_X + Math.floor(GRID_COLS / 2) * TILE_SIZE + TILE_SIZE / 2,
      y: MAP_OFFSET_Y + (GRID_ROWS - 1) * TILE_SIZE + TILE_SIZE / 2,
    };
    return this._cachedBasePos;
  },

  _updateExplosions(dt) {
    for (const exp of this._explosions) {
      exp.update(dt);
    }
  },

  _checkPowerUpPickup() {
    if (!this._playerTank.alive) return;

    const pb = this._playerTank.getBounds();
    for (const pu of this._powerUps) {
      if (!pu.alive) continue;
      const pub = pu.getBounds();

      if (
        pb.x < pub.x + pub.w &&
        pb.x + pb.w > pub.x &&
        pb.y < pub.y + pub.h &&
        pb.y + pb.h > pub.y
      ) {
        this._applyPowerUp(pu);
        pu.alive = false;
        GameGlobal.audioManager.playSFX('powerup');
      }
    }
  },

  _applyPowerUp(powerUp) {
    switch (powerUp.type) {
      case POWERUP_TYPE.STAR:
        this._playerTank.upgradeFireLevel();
        break;
      case POWERUP_TYPE.CLOCK:
        this._freezeTimer = FREEZE_DURATION;
        break;
      case POWERUP_TYPE.BOMB:
        // Destroy all on-screen enemies
        for (const enemy of this._enemies) {
          if (enemy.alive) {
            enemy.alive = false;
            this._spawnExplosion(enemy.x, enemy.y, true);
            this._recordKill(enemy);
          }
        }
        break;
      case POWERUP_TYPE.HELMET:
        this._playerTank.activateShield(SHIELD_DURATION);
        break;
      case POWERUP_TYPE.SHOVEL:
        this._mapManager.activateShovel(SHOVEL_DURATION);
        break;
      case POWERUP_TYPE.TANK:
        this._playerTank.addLife();
        break;
    }
  },

  _handleEnemyDestroyed(data) {
    const enemy = data.enemy;
    this._recordKill(enemy);

    // Spawn power-up if this enemy was marked
    if (enemy.hasPowerUp) {
      const type = PowerUp.randomType(this._level);
      const pos = PowerUp.randomPosition(this._mapManager);
      const pu = new PowerUp(type, pos.x, pos.y);
      this._powerUps.push(pu);
    }
  },

  _recordKill(enemy) {
    this._stats.totalKills++;
    this._stats.score += enemy.score || 100;

    switch (enemy.type) {
      case TANK_TYPE.ENEMY_NORMAL:
        this._stats.kills.normal++;
        break;
      case TANK_TYPE.ENEMY_FAST:
        this._stats.kills.fast++;
        break;
      case TANK_TYPE.ENEMY_ARMOR:
        this._stats.kills.armor++;
        break;
      case TANK_TYPE.ENEMY_BOSS:
        this._stats.kills.boss++;
        break;
    }
  },

  _handlePlayerDestroyed() {
    // Check if buff shield can absorb the hit
    if (this._buffManager && this._buffManager.consumeShield(this._playerTank)) {
      // Shield absorbed the damage, player survives
      this._playerTank.hp = 1;
      this._playerTank.alive = true;
      return;
    }

    const hasLives = this._playerTank.die();
    if (!hasLives) {
      // Always show revive dialog (escalating cost each time)
      this._showReviveAdDialog();
    }
  },

  /**
   * Check if revive ad can be shown.
   * @returns {boolean}
   * @private
   */
  _canShowReviveAd() {
    if (!GameGlobal.adManager) return false;
    const AdManager = require('../managers/AdManager');
    return GameGlobal.adManager.canShowScene(AdManager.AD_SCENE.REVIVE);
  },

  /**
   * Get the current revive gold cost based on revive count (escalating).
   * 1st revive: 200, 2nd: 400, 3rd+: 800
   * @returns {number}
   * @private
   */
  _getReviveCost() {
    if (this._reviveCount === 0) return 200;
    if (this._reviveCount === 1) return 400;
    return 800;
  },

  /**
   * Show the revive dialog overlay with dual options.
   * Pauses the game and presents watch-ad / gold-revive / give-up options.
   * @private
   */
  _showReviveAdDialog() {
    this._showingReviveDialog = true;
    this._paused = true;

    const cx = SCREEN_WIDTH / 2;
    const cy = SCREEN_HEIGHT / 2;
    const btnW = 220;
    const btnH = 36;

    // Check if ad is available
    const canShowAd = this._canShowReviveAd();

    const buttons = {
      giveUp: { x: cx - btnW / 2, y: cy + 50, w: btnW, h: btnH },
    };

    if (canShowAd) {
      buttons.watchAd = { x: cx - btnW / 2, y: cy - 20, w: btnW, h: btnH };
      buttons.goldRevive = { x: cx - btnW / 2, y: cy + 15, w: btnW, h: btnH };
      buttons.giveUp = { x: cx - btnW / 2, y: cy + 50, w: btnW, h: btnH };
    } else {
      // No ad available, only show gold revive and give up
      buttons.goldRevive = { x: cx - btnW / 2, y: cy - 5, w: btnW, h: btnH };
      buttons.giveUp = { x: cx - btnW / 2, y: cy + 35, w: btnW, h: btnH };
    }

    this._reviveDialogButtons = buttons;
  },

  /**
   * Handle the player choosing to revive with gold (escalating cost).
   * @private
   */
  _onGoldRevive() {
    const cost = this._getReviveCost();
    const cm = GameGlobal.currencyManager;
    if (cm && cm.spendGold(cost)) {
      this._showingReviveDialog = false;
      this._reviveDialogButtons = null;
      this._reviveCount++;
      this._revivePlayer();
      console.log(`[GameScene] Player revived via gold (${cost}), revive #${this._reviveCount}`);
    }
  },

  /**
   * Handle the player choosing to watch the revive ad.
   * @private
   */
  _onReviveAdWatch() {
    const AdManager = require('../managers/AdManager');
    GameGlobal.adManager.showRewardedVideoForScene(
      AdManager.AD_SCENE.REVIVE,
      (completed) => {
        this._showingReviveDialog = false;
        this._reviveDialogButtons = null;
        if (completed) {
          this._reviveCount++;
          this._revivePlayer();
        } else {
          this._triggerGameOver();
        }
      }
    );
  },

  /**
   * Handle the player choosing to give up (skip revive ad).
   * @private
   */
  _onReviveAdGiveUp() {
    this._showingReviveDialog = false;
    this._reviveDialogButtons = null;
    this._triggerGameOver();
  },

  /**
   * Revive the player: restore 1 life, keep fire level, respawn at start.
   * @private
   */
  _revivePlayer() {
    this._paused = false;
    this._playerTank.addLife();
    // Respawn: reset position, alive=true, hp=1, shield protection
    this._playerTank.respawn();
    console.log('[GameScene] Player revived');
  },

  /**
   * Trigger the game over state.
   * @private
   */
  _triggerGameOver() {
    this._paused = false;
    this._gameOver = true;
    this._stats.baseAlive = !this._mapManager.baseDestroyed;
    GameGlobal.audioManager.playSFX('gameover');
  },

  _handleBaseDestroyed() {
    this._gameOver = true;
    this._stats.baseAlive = false;
    GameGlobal.audioManager.playSFX('gameover');
  },

  _checkVictory() {
    if (this._gameOver || this._victory) return;

    const allSpawned = this._spawnManager.allSpawned;
    const allDead = this._enemies.every((e) => !e.alive);

    if (allSpawned && allDead) {
      this._victory = true;
      this._stats.baseAlive = !this._mapManager.baseDestroyed;
      GameGlobal.audioManager.playSFX('victory');

      // Time bonus
      const timeBonus = Math.max(0, 300 - Math.floor(this._stats.timeElapsed)) * 10;
      this._stats.score += timeBonus;

      // Base alive bonus
      if (this._stats.baseAlive) {
        this._stats.score += 1000;
      }
    }
  },

  _cleanup() {
    // Recycle dead bullets
    for (let i = this._bullets.length - 1; i >= 0; i--) {
      if (!this._bullets[i].alive) {
        this._bulletPool.put(this._bullets[i]);
        this._bullets.splice(i, 1);
      }
    }

    // Recycle dead explosions
    for (let i = this._explosions.length - 1; i >= 0; i--) {
      if (!this._explosions[i].alive) {
        this._explosionPool.put(this._explosions[i]);
        this._explosions.splice(i, 1);
      }
    }

    // Remove dead power-ups
    this._powerUps = this._powerUps.filter((pu) => pu.alive);

    // Remove dead enemies (keep for counting)
    // Don't remove - they're needed for allDead check
  },

  _transitionToResult() {
    const sm = GameGlobal.sceneManager;
    if (!sm._scenes.has(SCENE.RESULT)) {
      const ResultScene = require('./ResultScene');
      sm.register(SCENE.RESULT, ResultScene);
    }
    sm.switchTo(SCENE.RESULT, {
      level: this._level,
      mode: this._mode,
      victory: this._victory,
      stats: this._stats,
    });
  },

  // ============================================================
  // Touch Handling
  // ============================================================
  handleTouch(eventType, e) {
    if (this._gameOver || this._victory) return;

    // Handle revive dialog touches
    if (this._showingReviveDialog && eventType === 'touchstart') {
      const touches = e.touches;
      for (let i = 0; i < touches.length; i++) {
        const tx = touches[i].clientX;
        const ty = touches[i].clientY;
        const btns = this._reviveDialogButtons;
        if (btns) {
          // Watch Ad button
          if (btns.watchAd && tx >= btns.watchAd.x && tx <= btns.watchAd.x + btns.watchAd.w &&
              ty >= btns.watchAd.y && ty <= btns.watchAd.y + btns.watchAd.h) {
            this._onReviveAdWatch();
            return;
          }
          // Gold Revive button
          if (btns.goldRevive && tx >= btns.goldRevive.x && tx <= btns.goldRevive.x + btns.goldRevive.w &&
              ty >= btns.goldRevive.y && ty <= btns.goldRevive.y + btns.goldRevive.h) {
            this._onGoldRevive();
            return;
          }
          // Give Up button
          if (tx >= btns.giveUp.x && tx <= btns.giveUp.x + btns.giveUp.w &&
              ty >= btns.giveUp.y && ty <= btns.giveUp.y + btns.giveUp.h) {
            this._onReviveAdGiveUp();
            return;
          }
        }
      }
      return;
    }

    // Handle pause toggle
    if (this._paused) {
      if (eventType === 'touchstart') {
        this._paused = false;
      }
      return;
    }

    // Distribute touches to controls
    const touches = eventType === 'touchend' ? e.changedTouches : e.touches;
    for (let i = 0; i < touches.length; i++) {
      const touch = touches[i];

      // Try joystick first
      if (this._joystick.handleTouch(eventType, touch)) continue;

      // Then fire button
      if (this._fireButton.handleTouch(eventType, touch)) continue;

      // Pause button area (top-right corner)
      if (eventType === 'touchstart') {
        if (touch.clientX > SCREEN_WIDTH - 50 && touch.clientY < MAP_OFFSET_Y) {
          this._paused = true;
        }
      }
    }
  },
};

module.exports = GameScene;
