import { CombatEngine } from '../combat/CombatEngine.js';
import { CardObject } from '../objects/CardObject.js';
import { BattleField } from '../objects/BattleField.js';
import { SaveManager } from '../managers/SaveManager.js';

export class BattleScene extends Phaser.Scene {
  constructor() { super('BattleScene'); }

  init(data) {
    this.missionData = data.mission || null;
    this.playerDeckData = data.deck || null;
    this.isSkirmish = data.skirmish || false;
  }

  create() {
    const { width, height } = this.scale;
    const cardManager = this.registry.get('cardManager');
    const save = this.registry.get('save');

    // Layout constants
    // Lanes: 4 lanes centred at x = 430, 740, 1050, 1360  (spacing 310)
    // Commander column: x = 150
    // Opponent row: y = 305   Player row: y = 715   Midline: y = 510

    // Particle dot texture (white circle, 8×8) used for attack effects
    if (!this.textures.exists('particle_dot')) {
      const g = this.make.graphics({ x: 0, y: 0, add: false });
      g.fillStyle(0xffffff, 1);
      g.fillCircle(4, 4, 4);
      g.generateTexture('particle_dot', 8, 8);
      g.destroy();
    }

    // Sprite animations (global — skip if already registered from a previous battle)
    if (!this.anims.exists('attack_anim')) {
      this.anims.create({
        key: 'attack_anim',
        frames: this.anims.generateFrameNumbers('attacks', { start: 0, end: 4 }),
        frameRate: 10,
        repeat: 0
      });
    }
    if (!this.anims.exists('explosion_anim')) {
      this.anims.create({
        key: 'explosion_anim',
        frames: this.anims.generateFrameNumbers('attacks', { start: 5, end: 8 }),
        frameRate: 10,
        repeat: 0
      });
    }

    // Background
    this.add.rectangle(width / 2, height / 2, width, height, 0x1a1a2e);

    // Midfield divider
    this.add.rectangle(width / 2, 510, width, 2, 0x334466);

    // Vertical lane separators (5 lines bounding 4 lanes)
    for (let i = 0; i < 5; i++) {
      const x = 280 + i * 310;
      this.add.rectangle(x, 510, 1, 780, 0x222244);
    }

    // Commander column right edge
    this.add.rectangle(280, height / 2, 1, height, 0x222244);

    // Side labels
    this.add.text(14, 95, 'OPPONENT', { fontSize: '17px', color: '#ff8888' });
    this.add.text(14, 520, 'PLAYER', { fontSize: '17px', color: '#88aaff' });

    this.battlefield = new BattleField(this, {
      playerY: 715, opponentY: 305,
      commanderPlayerX: 150, commanderOpponentX: 150,
      laneStartX: 430, laneSpacing: 310
    });

    // Setup combat
    let opponentDeck;
    if (this.missionData) {
      opponentDeck = this.missionData.opponent;
    } else {
      // Skirmish: use a raider deck
      opponentDeck = {
        commander: 'raider_cmd_1',
        cards: [
          'raider_grunt_1', 'raider_grunt_1', 'raider_grunt_1',
          'raider_scout_1', 'raider_scout_1',
          'raider_berserker_1', 'raider_berserker_1',
          'raider_cutthroat_1', 'raider_marauder_1', 'raider_pillager_1'
        ]
      };
    }

    if (!this.playerDeckData) {
      this.playerDeckData = save.decks[0];
    }

    if (!this.playerDeckData) {
      this.add.text(width / 2, height / 2, 'No deck configured!\nGo to Deck Builder first.', {
        fontSize: '20px', color: '#ff4444', align: 'center'
      }).setOrigin(0.5);
      this._makeBackButton();
      return;
    }

    this.engine = new CombatEngine(this.playerDeckData, opponentDeck, cardManager);
    this.cardObjects = new Map(); // instanceId -> CardObject

    // Commander visuals
    this._buildCommanderDisplay();

    // ── Top bar ──────────────────────────────────────────────────────────────
    this.turnText = this.add.text(960, 30, 'Turn 0', {
      fontSize: '20px', color: '#ffffff'
    }).setOrigin(0.5);

    const battleLabel = this.missionData ? this.missionData.name : 'Skirmish Battle';
    this.add.text(960, 58, battleLabel, {
      fontSize: '14px', color: '#888888'
    }).setOrigin(0.5);

    // ── Combat log — bottom strip ────────────────────────────────────────────
    this.statusText = this.add.text(width / 2, 1058, 'Press SPACE or click Next Turn to start', {
      fontSize: '17px', color: '#aaaaaa'
    }).setOrigin(0.5);

    this.logLines = [];
    for (let i = 0; i < 6; i++) {
      this.logLines.push(this.add.text(14, 915 + i * 20, '', {
        fontSize: '15px', color: '#777777'
      }));
    }

    // ── Top bar buttons ─────────────────────────────────────────────────────
    this.autoPlay = false;
    this.autoTimer = null;
    this.waitingForPick = false;
    this.isAnimating = false;
    this.playerGoesFirst = true;
    this.initiativeIndicator = null;

    const autoBtn = this.add.rectangle(1680, 35, 180, 44, 0x224422)
      .setInteractive({ useHandCursor: true })
      .setStrokeStyle(1, 0x44aa44);
    this.autoBtnText = this.add.text(1680, 35, 'Auto: OFF', {
      fontSize: '18px', color: '#ffffff'
    }).setOrigin(0.5);
    autoBtn.on('pointerdown', () => this._toggleAuto());

    const nextBtn = this.add.rectangle(1840, 35, 180, 44, 0x1a3a5c)
      .setInteractive({ useHandCursor: true })
      .setStrokeStyle(1, 0x4488ff);
    this.add.text(1840, 35, 'Next Turn', {
      fontSize: '18px', color: '#ffffff'
    }).setOrigin(0.5);
    nextBtn.on('pointerdown', () => this._beginTurn());

    // Keyboard
    this.input.keyboard.on('keydown-SPACE', () => this._beginTurn());

    this._makeBackButton();
    this._renderState();
  }

  _buildCommanderDisplay() {
    const state = this.engine.getState();
    this.commanderObjects = new Map(); // instanceId → CardObject (persists across _renderState)

    const specs = [
      { data: state.opponent.commander, cx: 150, cy: 305, label: 'ENEMY CMD', labelColor: '#ff8888' },
      { data: state.player.commander, cx: 150, cy: 715, label: 'COMMANDER', labelColor: '#ffd700' }
    ];

    for (const s of specs) {
      const w = 240, h = 336;

      // Label above the card (separate text so it never scales/shakes with the card)
      this.add.text(s.cx, s.cy - h / 2 - 14, s.label,
        { fontSize: '15px', color: s.labelColor }).setOrigin(0.5);

      // Use CardObject for visual consistency with lane cards
      const cardObj = new CardObject(this, s.cx, s.cy, s.data, { width: w, height: h });
      cardObj.isCommander = true;

      this.commanderObjects.set(s.data.instanceId, cardObj);
    }

    this.oDeckText = this.add.text(14, 115, '', { fontSize: '15px', color: '#aaaaaa' });
    this.pDeckText = this.add.text(14, 540, '', { fontSize: '15px', color: '#aaaaaa' });
  }

  _beginTurn() {
    if (this.waitingForPick || this.isAnimating) return;
    if (this.engine.winner) { this._showResult(); return; }

    // Snapshot opponent lanes before this turn (only matters on opponent-first turns)
    const oldOpponentIds = new Set(
      this.engine.getState().opponent.lanes.map(c => c.instanceId)
    );

    const { hand, canDeploy, playerGoesFirst } = this.engine.beginTurn();
    this.playerGoesFirst = playerGoesFirst;
    this.turnText.setText(`Turn ${this.engine.turn}`);
    this._renderState();
    this._updateInitiativeIndicator(playerGoesFirst);

    const proceedAfterDeploy = () => {
      if (canDeploy && !this.autoPlay) {
        this.waitingForPick = true;
        this.statusText.setText('Choose a card to deploy');
        this._showCardPicker(hand);
      } else {
        this._finishTurn(canDeploy ? hand[0] : null);
      }
    };

    // On opponent-first turns, show enemy deploy animation before showing picker.
    // On player-first turns, opponent hasn't deployed yet — go straight to picker.
    const newOpponentCard = !playerGoesFirst
      ? this.engine.getState().opponent.lanes.find(c => !oldOpponentIds.has(c.instanceId))
      : null;

    if (newOpponentCard) {
      this.isAnimating = true;
      const cardObj = this.cardObjects.get(newOpponentCard.instanceId);
      this.statusText.setText(`Enemy deploys: ${newOpponentCard.name}`);
      this._animateDeploy(cardObj, () => {
        this.isAnimating = false;
        proceedAfterDeploy();
      });
    } else {
      proceedAfterDeploy();
    }
  }

  _finishTurn(chosenCard) {
    this.waitingForPick = false;
    this.isAnimating = true;
    this.statusText.setText('Deploying...');

    // Snapshot both sides before deploy so we can detect new cards
    const oldPlayerIds = new Set(
      this.engine.getState().player.lanes.map(c => c.instanceId)
    );
    const oldOpponentIds = new Set(
      this.engine.getState().opponent.lanes.map(c => c.instanceId)
    );

    // Deploy + pre-attack phases (NO damage applied yet)
    // On player-first turns, beginCommit also deploys the AI card
    this.engine.beginCommit(chosenCard);

    // Render the field with all newly deployed cards but pre-combat HP
    this._renderState();

    const newPlayerCard = chosenCard
      ? this.engine.getState().player.lanes.find(c => !oldPlayerIds.has(c.instanceId))
      : null;

    // On player-first turns the AI deployed inside beginCommit — animate it after player
    const newOpponentCard = this.playerGoesFirst
      ? this.engine.getState().opponent.lanes.find(c => !oldOpponentIds.has(c.instanceId))
      : null;

    const startAttacks = () => this.time.delayedCall(200, () => this._processNextAttackStep());

    const animateOpponentThenAttack = () => {
      if (newOpponentCard) {
        const cardObj = this.cardObjects.get(newOpponentCard.instanceId);
        this.statusText.setText(`Enemy deploys: ${newOpponentCard.name}`);
        this._animateDeploy(cardObj, startAttacks);
      } else {
        startAttacks();
      }
    };

    if (newPlayerCard) {
      const cardObj = this.cardObjects.get(newPlayerCard.instanceId);
      this.statusText.setText(`You deploy: ${newPlayerCard.name}`);
      this._animateDeploy(cardObj, animateOpponentThenAttack);
    } else {
      animateOpponentThenAttack();
    }
  }

  // Drive one attack at a time. Called recursively until all attacks are done.
  _processNextAttackStep() {
    if (!this.engine.hasPendingAttacks()) {
      // All attacks resolved — run death-check, win-check, then tidy up display
      this.engine.finalizeCommit();
      this._renderState(); // removes dead cards, shows clean final state

      const state = this.engine.getState();
      this.commanderObjects.get(state.player.commander.instanceId)?.refresh();
      this.commanderObjects.get(state.opponent.commander.instanceId)?.refresh();
      this.pDeckText.setText(`Deck:${state.player.deckRemaining} Hand:${state.player.hand.length}`);
      this.oDeckText.setText(`Deck:${state.opponent.deckRemaining} Hand:${state.opponent.hand.length}`);

      this.isAnimating = false;
      this._updateLog();
      this.statusText.setText('Press SPACE or click Next Turn to advance');
      if (this.engine.winner) {
        this.time.delayedCall(600, () => this._showResult());
      }
      return;
    }

    const events = this.engine.processNextAttack();
    const attackEvent = events.find(e => e.type === 'attack');

    if (!attackEvent) {
      // Attacker was already dead (counter-killed earlier this turn) — skip
      this.time.delayedCall(30, () => this._processNextAttackStep());
      return;
    }

    // Update commander HP bars immediately (siege / strike may have just hit)
    const state = this.engine.getState();
    this.commanderObjects.get(state.player.commander.instanceId)?.refresh();
    this.commanderObjects.get(state.opponent.commander.instanceId)?.refresh();

    const berserkEvent = events.find(e => e.type === 'berserk');

    this._animateAttack(attackEvent, () => {
      this._refreshCardAfterAttack(attackEvent.defender);
      this._refreshCardAfterAttack(attackEvent.attacker);
      this.time.delayedCall(220, () => this._processNextAttackStep());
    }, berserkEvent);
  }

  // Update a card's HP bar and stats at the moment of impact, then handle death.
  // If the defender was already killed via _onAttackReconcile, cardObjects.get() returns
  // null here and the function exits early — no double-death.
  _refreshCardAfterAttack(cardData) {
    if (!cardData) return;
    const obj = this.cardObjects.get(cardData.instanceId)
      ?? this.commanderObjects?.get(cardData.instanceId);
    if (!obj) return;
    obj.refresh();
    // Fallback death path for cards killed by counter/rupture without an HP loss animation
    if (cardData.currentHP <= 0 && !obj.isCommander) {
      this._playCardDeath(obj, cardData);
    }
  }

  // Explosion sprite + fade-out for a defeated lane card.
  _playCardDeath(obj, cardData) {
    this.cardObjects.delete(cardData.instanceId);

    this.tweens.killTweensOf(obj);
    obj.setScale(1).setDepth(0);

    const explosionSprite = this.add.sprite(obj.x, obj.y, 'attacks')
      .setDisplaySize(630, 630)
      .setDepth(23);
    explosionSprite.play('explosion_anim');
    explosionSprite.once('animationcomplete', () => {
      if (explosionSprite.scene) explosionSprite.destroy();
      if (!obj.scene) return;
      this.tweens.add({
        targets: obj,
        scaleX: 1.25, scaleY: 1.25,
        alpha: 0,
        duration: 400,
        ease: 'Power2',
        onComplete: () => { if (obj.scene) obj.destroy(); }
      });
    });
  }

  // Animate a card appearing on the field (scale from 0 with overshoot)
  _animateDeploy(cardObj, onComplete) {
    if (!cardObj) { onComplete(); return; }
    cardObj.setScale(0).setAlpha(0);
    this.tweens.add({
      targets: cardObj,
      scaleX: 1.12, scaleY: 1.12,
      alpha: 1,
      duration: 280,
      ease: 'Back.Out',
      onComplete: () => {
        this.tweens.add({
          targets: cardObj,
          scaleX: 1, scaleY: 1,
          duration: 180,
          ease: 'Power2',
          onComplete
        });
      }
    });
  }

  // Animate a single attack.
  // Cards slide to center (attacker left, defender right), scale up, hold while
  // particle burst + shake + damage number play, then scale down and slide back.
  _animateAttack(event, onComplete, berserkEvent = null) {
    const SCALE = 1.78;
    const SCALE_UP_MS = 280;
    const HOLD_MS = 3100;
    const SCALE_DN_MS = 280;
    const ATTACK_MS = SCALE_UP_MS + HOLD_MS + SCALE_DN_MS; // 1660 ms

    const { width, height } = this.scale;
    const cardW = 260;
    const enlargedW = cardW * SCALE;          // ~463px at 1.78×
    const gap = enlargedW * 0.75;       // ~347px between enlarged cards
    const attackerDestX = width / 2 - gap / 2 - enlargedW / 2; // ~554
    const defenderDestX = width / 2 + gap / 2 + enlargedW / 2; // ~1366
    const centerY = height / 2;                       // 540

    const _lookup = id => id && (this.cardObjects.get(id) || this.commanderObjects?.get(id));
    const attackerObj = _lookup(event.attacker.instanceId);
    const defenderObj = _lookup(event.defender?.instanceId);

    // Save original positions so we can slide cards back afterward
    const attackerOrigX = attackerObj?.x;
    const attackerOrigY = attackerObj?.y;
    const defenderOrigX = defenderObj?.x;
    const defenderOrigY = defenderObj?.y;

    const attName = event.attacker.name;
    const defName = event.defender?.name ?? 'Commander';
    this.statusText.setText(`${attName}  ⚔  ${defName}  —  ${event.damage} damage!`);

    // ── Slide to center + scale up, hold, slide back + scale down ────────────
    const enlargeCard = (obj, cardRef, destX, origX, origY) => {
      if (!obj) return;
      obj.setDepth(20);

      // Scale up (Back.Out for the snappy overshoot feel)
      this.tweens.add({
        targets: obj,
        scaleX: SCALE, scaleY: SCALE,
        duration: SCALE_UP_MS,
        ease: 'Back.Out'
      });

      // Slide to battle center (smooth Power2)
      this.tweens.add({
        targets: obj,
        x: destX, y: centerY,
        duration: SCALE_UP_MS,
        ease: 'Power2.inOut',
        onComplete: () => {
          this.time.delayedCall(HOLD_MS, () => {
            if (!obj.scene) return;
            // Dead cards stay at center — _refreshCardAfterAttack handles their death
            if (cardRef.currentHP > 0) {
              this.tweens.add({
                targets: obj,
                scaleX: 1, scaleY: 1,
                duration: SCALE_DN_MS,
                ease: 'Power2',
                onComplete: () => { if (obj.scene) obj.setDepth(0); }
              });
              this.tweens.add({
                targets: obj,
                x: origX, y: origY,
                duration: SCALE_DN_MS,
                ease: 'Power2'
              });
            }
          });
        }
      });
    };

    enlargeCard(attackerObj, event.attacker, attackerDestX, attackerOrigX, attackerOrigY);
    enlargeCard(defenderObj, event.defender ?? { currentHP: 1 }, defenderDestX, defenderOrigX, defenderOrigY);

    // ── VS image — appears between cards once they arrive at center ───────────
    let vsImage = null;
    this.time.delayedCall(SCALE_UP_MS, () => {
      if (!this.textures.exists('vs')) return;
      vsImage = this.add.image(width / 2, centerY, 'vs')
        .setDisplaySize(Math.round(gap * 0.85), Math.round(gap * 0.85))
        .setDepth(25)
        .setAlpha(0);
      this.tweens.add({ targets: vsImage, alpha: 1, duration: 150, ease: 'Power2' });
    });
    this.time.delayedCall(SCALE_UP_MS + HOLD_MS, () => {
      if (!vsImage?.scene) return;
      this.tweens.add({
        targets: vsImage, alpha: 0, duration: SCALE_DN_MS, ease: 'Power2',
        onComplete: () => { if (vsImage?.scene) vsImage.destroy(); }
      });
    });

    // ── Attacker: attack sprite + particle burst — fires once card arrives at center ──
    if (attackerObj) {
      const enlargedH = 364 * SCALE;
      this.time.delayedCall(SCALE_UP_MS, () => {
        if (!attackerObj.scene) return;

        // Gun turret animation centered on the attacking card
        const attackSprite = this.add.sprite(
          attackerDestX,
          centerY,
          'attacks'
        ).setDisplaySize(480, 480).setDepth(22);
        attackSprite.play('attack_anim');
        attackSprite.once('animationcomplete', () => {
          if (attackSprite.scene) attackSprite.destroy();
          this._onAttackReconcile(event, berserkEvent);
        });

        const emitter = this.add.particles(attackerDestX, centerY, 'particle_dot', {
          speed: { min: 90, max: 300 },
          scale: { start: 1.8, end: 0 },
          alpha: { start: 1, end: 0 },
          lifespan: 650,
          tint: [0xff8800, 0xffee00, 0xffffff, 0x88ccff, 0xff44ff],
          blendMode: 'ADD',
          emitZone: {
            type: 'edge',
            source: new Phaser.Geom.Rectangle(-enlargedW / 2, -enlargedH / 2, enlargedW, enlargedH),
            quantity: 56
          },
          stopAfter: 56
        });
        this.time.delayedCall(800, () => { if (emitter?.scene) emitter.destroy(); });
      });
    }

    // ── Defender: shake + red flash + HP update + floating damage number ──────
    // Fires once both cards are fully enlarged at center
    this.time.delayedCall(SCALE_UP_MS + 80, () => {
      if (defenderObj?.scene) {
        defenderObj.refresh();

        // Flash red overlay → fade out
        defenderObj.bg.setAlpha(0.70);
        this.tweens.add({
          targets: defenderObj.bg,
          alpha: 0,
          duration: 600,
          ease: 'Power2'
        });

        // Shake around the defender's center position
        const shakeX = defenderObj.x;
        this.tweens.add({
          targets: defenderObj,
          x: { from: shakeX - 26, to: shakeX + 26 },
          duration: 60,
          yoyo: true,
          repeat: 6,
          ease: 'Linear',
          onComplete: () => { if (defenderObj.scene) defenderObj.x = shakeX; }
        });
      }

      // Floating damage number above the defender at center
      const dmgAnchorX = defenderDestX;
      const dmgAnchorY = centerY;
      const dmgText = this.add.text(
        dmgAnchorX, dmgAnchorY - 100,
        `-${event.damage}`,
        { fontSize: '56px', color: '#ff3333', stroke: '#000000', strokeThickness: 5 }
      ).setOrigin(0.5).setDepth(30);

      this.tweens.add({
        targets: dmgText,
        y: dmgAnchorY - 250,
        alpha: 0,
        duration: 1300,
        ease: 'Power2',
        onComplete: () => dmgText.destroy()
      });
    });

    this.time.delayedCall(ATTACK_MS, onComplete);
  }

  // Fires when the attack animation ends — attach all post-attack consequences here.
  _onAttackReconcile(event, berserkEvent) {
    const _lookup = id => id && (this.cardObjects.get(id) || this.commanderObjects?.get(id));
    const defenderObj = _lookup(event.defender?.instanceId);
    const attackerObj = _lookup(event.attacker?.instanceId);

    // HP loss animation on defender; on completion, trigger death if HP reached zero
    if (defenderObj?.scene && event.damage > 0) {
      defenderObj.animateHPLoss(event.damage, () => {
        if (event.defender.currentHP <= 0 && !defenderObj.isCommander) {
          this._playCardDeath(defenderObj, event.defender);
        }
      });
    }

    // Berserk ATK gain animation on attacker
    if (berserkEvent && attackerObj?.scene) {
      attackerObj.atkText.setText(`${berserkEvent.card.currentAttack - berserkEvent.gain}`);
      attackerObj.animateBerserkGain(berserkEvent.gain);
    }
  }

  _showCardPicker(hand) {
    const { width, height } = this.scale;

    this._destroyCardPicker();
    this.pickerObjects = [];

    // Dim overlay
    const overlay = this.add.rectangle(width / 2, height / 2, width, height, 0x000000, 0.60)
      .setDepth(10);
    this.pickerObjects.push(overlay);

    // Panel background
    const cardW = 260, cardH = 364;
    const gap = 40;
    const panelPadX = 60, panelPadY = 70;
    const totalW = hand.length * cardW + (hand.length - 1) * gap;
    const panelW = Math.max(totalW + panelPadX * 2, 500);
    const panelH = cardH + panelPadY * 2;
    const panelY = 540;

    const panel = this.add.rectangle(width / 2, panelY, panelW, panelH, 0x0d1b2a, 0.97)
      .setStrokeStyle(2, 0x4488ff)
      .setDepth(10);
    this.pickerObjects.push(panel);

    const title = this.add.text(width / 2, panelY - panelH / 2 + 26, 'Choose a card to deploy', {
      fontSize: '22px', color: '#d4af37'
    }).setOrigin(0.5).setDepth(11);
    this.pickerObjects.push(title);

    const startX = width / 2 - totalW / 2 + cardW / 2;
    const cardY = panelY + 8;

    hand.forEach((card, i) => {
      const x = startX + i * (cardW + gap);

      // CardObject at depth 11
      const cardObj = new CardObject(this, x, cardY, card, { width: cardW, height: cardH });
      cardObj.setDepth(11);
      this.pickerObjects.push(cardObj);

      // Invisible interactive hit rect on top
      const hitRect = this.add.rectangle(x, cardY, cardW, cardH, 0xffffff, 0)
        .setInteractive({ useHandCursor: true })
        .setDepth(12);

      hitRect.on('pointerover', () => {
        cardObj.setScale(1.05);
        cardObj.setDepth(13);
      });
      hitRect.on('pointerout', () => {
        cardObj.setScale(1);
        cardObj.setDepth(11);
      });
      hitRect.on('pointerdown', () => {
        this._destroyCardPicker();
        this._finishTurn(card);
      });

      this.pickerObjects.push(hitRect);
    });

    // Pass button
    const passBtn = this.add.rectangle(width / 2, panelY + panelH / 2 - 28, 220, 44, 0x333333)
      .setStrokeStyle(1, 0x888888)
      .setInteractive({ useHandCursor: true })
      .setDepth(11);
    const passTxt = this.add.text(width / 2, panelY + panelH / 2 - 28, 'Pass (deploy nothing)', {
      fontSize: '17px', color: '#aaaaaa'
    }).setOrigin(0.5).setDepth(12);
    passBtn.on('pointerdown', () => {
      this._destroyCardPicker();
      this._finishTurn(null);
    });
    this.pickerObjects.push(passBtn, passTxt);
  }

  _destroyCardPicker() {
    if (this.pickerObjects) {
      this.pickerObjects.forEach(o => o.destroy());
      this.pickerObjects = null;
    }
  }

  _renderState() {
    const state = this.engine.getState();

    this.cardObjects.forEach(co => co.destroy());
    this.cardObjects.clear();

    state.player.lanes.forEach((card, i) => {
      const pos = this.battlefield.getPlayerLanePos(i);
      const co = new CardObject(this, pos.x, pos.y, card, { width: 260, height: 364 });
      this.cardObjects.set(card.instanceId, co);
    });

    state.opponent.lanes.forEach((card, i) => {
      const pos = this.battlefield.getOpponentLanePos(i);
      const co = new CardObject(this, pos.x, pos.y, card, { width: 260, height: 364 });
      this.cardObjects.set(card.instanceId, co);
    });
  }

  _updateLog() {
    const recent = this.engine.log.slice(-6);
    this.logLines.forEach((line, i) => {
      line.setText(recent[i] || '');
    });
  }

  _toggleAuto() {
    this.autoPlay = !this.autoPlay;
    this.autoBtnText.setText(`Auto: ${this.autoPlay ? 'ON' : 'OFF'}`);
    if (this.autoPlay) {
      this.autoTimer = this.time.addEvent({
        delay: 300,
        callback: () => {
          if (!this.engine.winner) {
            this._beginTurn();
          } else {
            this.autoPlay = false;
            this.autoBtnText.setText('Auto: OFF');
            if (this.autoTimer) this.autoTimer.remove();
          }
        },
        loop: true
      });
    } else {
      if (this.autoTimer) this.autoTimer.remove();
    }
  }

  _showResult() {
    if (this.autoTimer) this.autoTimer.remove();
    const { width, height } = this.scale;
    const won = this.engine.winner === 'player';
    const save = this.registry.get('save');

    // Overlay
    this.add.rectangle(width / 2, height / 2, width, height, won ? 0x003300 : 0x330000, 0.75);

    this.add.text(width / 2, height / 2 - 120, won ? 'VICTORY!' : 'DEFEAT', {
      fontSize: '72px', color: won ? '#44ff44' : '#ff4444',
      stroke: '#000000', strokeThickness: 6
    }).setOrigin(0.5);

    this.add.text(width / 2, height / 2 - 40, `Battle lasted ${this.engine.turn} turns`, {
      fontSize: '24px', color: '#aaaaaa'
    }).setOrigin(0.5);

    if (won && this.missionData) {
      const rewards = this.missionData.rewards;
      SaveManager.addGold(save, rewards.gold);
      SaveManager.completeMission(save, this.missionData.id);
      if (rewards.cards) {
        rewards.cards.forEach(cardId => SaveManager.addCard(save, cardId));
      }
      this.registry.set('save', save);

      this.add.text(width / 2, height / 2 + 20, `+${rewards.gold} Gold`, {
        fontSize: '36px', color: '#ffd700'
      }).setOrigin(0.5);

      if (rewards.cards && rewards.cards.length > 0) {
        const cardManager = this.registry.get('cardManager');
        const cardNames = rewards.cards.map(id => {
          const c = cardManager.getCard(id);
          return c ? c.name : id;
        }).join(', ');
        this.add.text(width / 2, height / 2 + 70, `New card(s): ${cardNames}`, {
          fontSize: '22px', color: '#aaffaa'
        }).setOrigin(0.5);
      }
    } else if (!won) {
      this.add.text(width / 2, height / 2 + 20, 'Better luck next time!', {
        fontSize: '24px', color: '#aaaaaa'
      }).setOrigin(0.5);
    }

    const backBtn = this.add.rectangle(width / 2, height / 2 + 160, 260, 60, 0x1a3a5c)
      .setInteractive({ useHandCursor: true })
      .setStrokeStyle(2, 0x4488ff);
    this.add.text(width / 2, height / 2 + 160, 'Continue', {
      fontSize: '28px', color: '#ffffff'
    }).setOrigin(0.5);
    backBtn.on('pointerdown', () => this.scene.start(this.missionData ? 'CampaignScene' : 'MainMenuScene'));
  }

  _updateInitiativeIndicator(playerGoesFirst) {
    if (this.initiativeIndicator) {
      this.initiativeIndicator.destroy();
      this.initiativeIndicator = null;
    }
    if (!this.textures.exists('attacksFirst')) return;
    // Position the indicator to the left of the commander card (commander at x=150, width=240)
    const indicatorX = 22;
    const indicatorY = playerGoesFirst ? 715 : 305;
    this.initiativeIndicator = this.add.image(indicatorX, indicatorY, 'attacksFirst')
      .setDisplaySize(44, 44)
      .setDepth(5);
  }

  _makeBackButton() {
    const bg = this.add.rectangle(80, 35, 180, 44, 0x333333)
      .setInteractive({ useHandCursor: true })
      .setStrokeStyle(1, 0x888888);
    this.add.text(80, 35, '← Back', { fontSize: '18px', color: '#ffffff' }).setOrigin(0.5);
    bg.on('pointerdown', () => {
      if (this.autoTimer) this.autoTimer.remove();
      this.scene.start('MainMenuScene');
    });
  }
}
