import puppeteer from 'puppeteer';

const BASE_URL = 'https://el3ab-player.caprover.al-arcade.com';
const TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkMTRhMjdjNi0yNDQ4LTQzMTktYTc3NS1hOWY5NGRkNmRlODciLCJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzgwNzMzOTIxLCJpYXQiOjE3ODA3MzAzMjEsImVtYWlsIjoidGVzdHBsYXllcjFAZWwzYWIuY29tIiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCIsInByb3ZpZGVycyI6WyJlbWFpbCJdfSwidXNlcl9tZXRhZGF0YSI6eyJkaXNwbGF5X25hbWUiOiLZhNin2LnYqCDYp9iu2KrYqNin2LEiLCJlbWFpbCI6InRlc3RwbGF5ZXIxQGVsM2FiLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwaG9uZV92ZXJpZmllZCI6ZmFsc2UsInN1YiI6ImQxNGEyN2M2LTI0NDgtNDMxOS1hNzc1LWE5Zjk0ZGQ2ZGU4NyIsInVzZXJuYW1lIjoidGVzdHBsYXllcjEifSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTc4MDczMDMyMX1dLCJzZXNzaW9uX2lkIjoiZjcxZDRmZDktOWU3YS00ZTk1LWIwNDItNzM2YmQ5MjIxODYyIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.xJmblxW4Kgf0vBZlDV6K8AOyolAOuijgMmz9z8De-58';
const USER_ID = 'd14a27c6-2448-4319-a775-a9f94dd6de87';
const wait = ms => new Promise(r => setTimeout(r, ms));

let passed = 0, failed = 0;
const results = [];

function assert(condition, label) {
  if (condition) {
    passed++;
    results.push(`  ✓ ${label}`);
  } else {
    failed++;
    results.push(`  ✗ FAIL: ${label}`);
  }
}

async function run() {
  const browser = await puppeteer.launch({
    headless: true,
    args: ['--no-sandbox', '--disable-setuid-sandbox', '--ignore-certificate-errors']
  });

  const page = await browser.newPage();
  await page.setViewport({ width: 390, height: 844, deviceScaleFactor: 2 });

  const jsErrors = [];
  page.on('console', msg => { if (msg.type() === 'error') jsErrors.push(msg.text()); });
  page.on('pageerror', err => jsErrors.push(`PAGE_ERROR: ${err.message}`));

  // ===== BOOT & AUTH =====
  console.log('\n═══════════════════════════════════');
  console.log(' BACKGAMMON EDGE CASE TEST SUITE');
  console.log('═══════════════════════════════════\n');

  console.log('[BOOT] Loading app...');
  await page.goto(BASE_URL, { waitUntil: 'networkidle2', timeout: 30000 });

  await page.evaluate((token, userId) => {
    localStorage.setItem('el3ab_state', JSON.stringify({
      auth: { token, refreshToken: 'dummy', userId },
      player: { id: userId, display_name: 'لاعب اختبار', username: 'testplayer1', level: 5, coins: 1000, xp: 500 },
      activeWorld: 'play', audioEnabled: false, language: 'ar'
    }));
  }, TOKEN, USER_ID);

  await page.reload({ waitUntil: 'networkidle2', timeout: 30000 });
  await wait(2500);
  console.log('[BOOT] Authenticated\n');

  // ═══════════════════════════════════════
  // TEST 1: ROOM SCENE — NAVIGATION
  // ═══════════════════════════════════════
  console.log('━━━ TEST 1: Room Scene Navigation ━━━');

  await page.click('[data-game="backgammon"]');
  await wait(1200);

  const roomState = await page.evaluate(() => {
    const wrap = document.querySelector('.bg-wrap');
    const title = document.querySelector('.bg-title');
    const btns = document.querySelectorAll('.bg-btn');
    return {
      hasWrap: !!wrap,
      titleText: title?.textContent || '',
      btnCount: btns.length,
      btnTexts: [...btns].map(b => b.querySelector('.bg-btn-label')?.textContent || b.textContent.trim().slice(0, 20))
    };
  });

  assert(roomState.hasWrap, 'Room scene renders .bg-wrap');
  assert(roomState.titleText.includes('طاولة'), 'Title shows "طاولة"');
  assert(roomState.btnCount >= 3, 'Has 3+ action buttons (bot, online, friend)');
  assert(roomState.btnTexts.some(t => t.includes('البوت')), 'Has "ضد البوت" button');
  assert(roomState.btnTexts.some(t => t.includes('أونلاين')), 'Has "أونلاين" button');
  assert(roomState.btnTexts.some(t => t.includes('صديق')), 'Has "تحدي صديق" button');

  await page.screenshot({ path: '/tmp/bg-01-room.png' });

  // ═══════════════════════════════════════
  // TEST 2: SETUP SCENE — ALL OPTIONS
  // ═══════════════════════════════════════
  console.log('━━━ TEST 2: Setup Scene Options ━━━');

  // Click "ضد البوت"
  await page.evaluate(() => {
    const btn = document.querySelector('#btn-local');
    if (btn) btn.click();
  });
  await wait(800);

  const setupState = await page.evaluate(() => {
    const variantBtns = [...document.querySelectorAll('#variant-grid .bg-chip')];
    const lengthBtns = [...document.querySelectorAll('#length-grid .bg-chip')];
    const diffBtns = [...document.querySelectorAll('#difficulty-grid .bg-chip')];
    const cubeBtns = [...document.querySelectorAll('#cube-grid .bg-chip')];
    const startBtn = document.querySelector('#btn-start');
    return {
      variants: variantBtns.map(b => ({ text: b.textContent.trim(), active: b.classList.contains('bg-chip-active'), variant: b.dataset.variant })),
      lengths: lengthBtns.map(b => ({ text: b.textContent.trim(), len: b.dataset.len })),
      diffs: diffBtns.map(b => ({ text: b.textContent.trim(), diff: b.dataset.diff })),
      cubeOptions: cubeBtns.map(b => ({ text: b.textContent.trim(), cube: b.dataset.cube })),
      hasStart: !!startBtn
    };
  });

  assert(setupState.variants.length === 3, 'Has 3 variants');
  assert(setupState.variants.some(v => v.text.includes('شيش بيش')), 'Has شيش بيش variant');
  assert(setupState.variants.some(v => v.text.includes('محبوسة')), 'Has محبوسة variant');
  assert(setupState.variants.some(v => v.text.includes('٣١')), 'Has ٣١ variant');
  assert(setupState.variants.find(v => v.variant === 'sheshbesh')?.active, 'شيش بيش is default active');
  assert(setupState.lengths.length === 4, 'Has 4 match length options (1,3,5,7)');
  assert(setupState.diffs.length === 3, 'Has 3 difficulty levels');
  assert(setupState.cubeOptions.length === 2, 'Has cube on/off toggle');
  assert(setupState.hasStart, 'Has start button');

  await page.screenshot({ path: '/tmp/bg-02-setup.png' });

  // Test variant switching
  await page.evaluate(() => {
    const btn = [...document.querySelectorAll('#variant-grid .bg-chip')].find(b => b.dataset.variant === 'mahbousa');
    if (btn) btn.click();
  });
  await wait(300);

  const variantSwitch = await page.evaluate(() => {
    const active = document.querySelector('#variant-grid .bg-chip-active');
    return active?.dataset.variant;
  });
  assert(variantSwitch === 'mahbousa', 'Variant switch to محبوسة works');

  // Switch back to sheshbesh
  await page.evaluate(() => {
    const btn = [...document.querySelectorAll('#variant-grid .bg-chip')].find(b => b.dataset.variant === 'sheshbesh');
    if (btn) btn.click();
  });
  await wait(200);

  // ═══════════════════════════════════════
  // TEST 3: START GAME — SHESHBESH (standard)
  // ═══════════════════════════════════════
  console.log('━━━ TEST 3: Start Game (شيش بيش) ━━━');

  await page.evaluate(() => {
    const btn = document.querySelector('#btn-start');
    if (btn) btn.click();
  });
  await wait(2000);

  const gameState = await page.evaluate(() => {
    const container = document.querySelector('.bgg-container');
    const canvas = document.querySelector('#bg-canvas');
    const rollBtn = document.querySelector('#btn-roll');
    const nameTop = document.querySelector('#name-top');
    const nameBottom = document.querySelector('#name-bottom');
    const pipsTop = document.querySelector('#pips-top');
    const pipsBottom = document.querySelector('#pips-bottom');
    const scoreTop = document.querySelector('#score-top');
    const scoreBottom = document.querySelector('#score-bottom');
    const turnIndicator = document.querySelector('#turn-indicator');
    const emoteBtn = document.querySelector('#btn-emote');
    const quitBtn = document.querySelector('#btn-quit');
    const cubeArea = document.querySelector('#cube-area');
    const diceArea = document.querySelector('.bgg-dice-area');

    return {
      hasContainer: !!container,
      hasCanvas: !!canvas,
      canvasW: canvas?.width,
      canvasH: canvas?.height,
      hasRollBtn: !!rollBtn,
      rollBtnVisible: rollBtn ? getComputedStyle(rollBtn).display !== 'none' : false,
      nameTop: nameTop?.textContent || '',
      nameBottom: nameBottom?.textContent || '',
      pipsTop: pipsTop?.textContent || '',
      pipsBottom: pipsBottom?.textContent || '',
      scoreTop: scoreTop?.textContent || '',
      scoreBottom: scoreBottom?.textContent || '',
      turnText: turnIndicator?.textContent || '',
      hasEmoteBtn: !!emoteBtn,
      hasQuitBtn: !!quitBtn,
      hasCubeArea: !!cubeArea,
      hasDiceArea: !!diceArea
    };
  });

  assert(gameState.hasContainer, 'Game container renders');
  assert(gameState.hasCanvas, 'Canvas element exists');
  assert(gameState.canvasW > 0 && gameState.canvasH > 0, `Canvas has size ${gameState.canvasW}x${gameState.canvasH}`);
  assert(gameState.hasRollBtn, 'Roll dice button exists');
  assert(gameState.rollBtnVisible, 'Roll button is visible (my turn first)');
  assert(gameState.nameTop.includes('بوت'), 'Top player shows "بوت"');
  assert(gameState.nameBottom.includes('أنت'), 'Bottom player shows "أنت"');
  assert(gameState.pipsTop.includes('نقطة'), 'Top pip count shows');
  assert(gameState.pipsBottom.includes('نقطة'), 'Bottom pip count shows');
  assert(gameState.scoreTop === '0', 'Initial score top is 0');
  assert(gameState.scoreBottom === '0', 'Initial score bottom is 0');
  assert(gameState.turnText.includes('دورك'), 'Turn indicator shows "دورك"');
  assert(gameState.hasEmoteBtn, 'Emote button exists');
  assert(gameState.hasQuitBtn, 'Quit button exists');
  assert(gameState.hasCubeArea, 'Doubling cube area exists');

  await page.screenshot({ path: '/tmp/bg-03-game-start.png' });

  // ═══════════════════════════════════════
  // TEST 4: DICE ROLLING
  // ═══════════════════════════════════════
  console.log('━━━ TEST 4: Dice Rolling ━━━');

  // Roll the dice
  await page.evaluate(() => {
    const btn = document.querySelector('#btn-roll');
    if (btn) btn.click();
  });
  await wait(1500);

  const afterRoll = await page.evaluate(() => {
    const rollBtn = document.querySelector('#btn-roll');
    return {
      rollBtnHidden: rollBtn ? getComputedStyle(rollBtn).display === 'none' : true,
      // Check game state via module
      canvasDataLen: document.querySelector('#bg-canvas')?.toDataURL()?.length || 0
    };
  });

  assert(afterRoll.rollBtnHidden, 'Roll button hidden after rolling');
  assert(afterRoll.canvasDataLen > 5000, 'Canvas rendered after roll (has content)');

  await page.screenshot({ path: '/tmp/bg-04-after-roll.png' });

  // ═══════════════════════════════════════
  // TEST 5: PIECE SELECTION & VALID MOVES
  // ═══════════════════════════════════════
  console.log('━━━ TEST 5: Piece Selection & Moves ━━━');

  // Tap on various board positions to test interaction
  // White pieces start at points 5, 7, 12, 23 in standard setup
  // Point 5 (white home) is bottom-right area on canvas
  const canvasRect = await page.evaluate(() => {
    const c = document.querySelector('#bg-canvas');
    if (!c) return null;
    const r = c.getBoundingClientRect();
    return { x: r.x, y: r.y, w: r.width, h: r.height };
  });

  if (canvasRect) {
    // Tap roughly where point 5 would be (bottom row, 6th from right)
    const tapX = canvasRect.x + canvasRect.w * 0.62;
    const tapY = canvasRect.y + canvasRect.h * 0.85;
    await page.mouse.click(tapX, tapY);
    await wait(500);

    const afterTap = await page.evaluate(() => {
      const c = document.querySelector('#bg-canvas');
      return { canvasData: c?.toDataURL()?.length || 0 };
    });
    assert(afterTap.canvasData > 5000, 'Canvas re-renders after tap (selection or no-op)');
    await page.screenshot({ path: '/tmp/bg-05-after-tap.png' });

    // Try tapping point 23 area (top-right, where white has 2 pieces)
    const tapX2 = canvasRect.x + canvasRect.w * 0.88;
    const tapY2 = canvasRect.y + canvasRect.h * 0.15;
    await page.mouse.click(tapX2, tapY2);
    await wait(500);
    await page.screenshot({ path: '/tmp/bg-05b-point23-tap.png' });

    // Tap point 12 area (top-left area)
    const tapX3 = canvasRect.x + canvasRect.w * 0.08;
    const tapY3 = canvasRect.y + canvasRect.h * 0.15;
    await page.mouse.click(tapX3, tapY3);
    await wait(500);
    await page.screenshot({ path: '/tmp/bg-05c-point12-tap.png' });
  }

  // ═══════════════════════════════════════
  // TEST 6: FULL TURN CYCLE — BOT PLAYS
  // ═══════════════════════════════════════
  console.log('━━━ TEST 6: Full Turn Cycle ━━━');

  // Let the bot play its turn by waiting
  // First we need to force-execute a move for our turn
  // We'll interact with the game logic directly
  const turnCycle = await page.evaluate(() => {
    // Wait up to 5 seconds for the bot to play
    return new Promise(resolve => {
      let checks = 0;
      const iv = setInterval(() => {
        checks++;
        const indicator = document.querySelector('#turn-indicator');
        const rollBtn = document.querySelector('#btn-roll');
        const rollVisible = rollBtn && getComputedStyle(rollBtn).display !== 'none';

        if (rollVisible && checks > 2) {
          clearInterval(iv);
          resolve({ turnSwitched: true, indicatorText: indicator?.textContent, checks });
        }
        if (checks > 20) {
          clearInterval(iv);
          resolve({ turnSwitched: false, indicatorText: indicator?.textContent, checks });
        }
      }, 500);
    });
  });

  // The bot may or may not have played depending on whether we completed our turn
  console.log('   Turn cycle result:', turnCycle.indicatorText, 'checks:', turnCycle.checks);
  await page.screenshot({ path: '/tmp/bg-06-turn-cycle.png' });

  // ═══════════════════════════════════════
  // TEST 7: EMOTE PANEL
  // ═══════════════════════════════════════
  console.log('━━━ TEST 7: Emote Panel ━━━');

  await page.evaluate(() => {
    const btn = document.querySelector('#btn-emote');
    if (btn) btn.click();
  });
  await wait(500);

  const emoteState = await page.evaluate(() => {
    const panel = document.querySelector('#emote-panel');
    const emotes = panel?.querySelectorAll('.bgg-emote-btn');
    const phrases = panel?.querySelectorAll('.bgg-phrase-btn');
    return {
      panelVisible: panel ? getComputedStyle(panel).display !== 'none' : false,
      emoteCount: emotes?.length || 0,
      phraseCount: phrases?.length || 0,
      firstEmote: emotes?.[0]?.textContent || '',
      firstPhrase: phrases?.[0]?.textContent || ''
    };
  });

  assert(emoteState.panelVisible, 'Emote panel opens on click');
  assert(emoteState.emoteCount === 8, `Has 8 emotes (got ${emoteState.emoteCount})`);
  assert(emoteState.phraseCount === 6, `Has 6 phrases (got ${emoteState.phraseCount})`);
  assert(emoteState.firstEmote === '🎲', 'First emote is 🎲');

  await page.screenshot({ path: '/tmp/bg-07-emote-panel.png' });

  // Send an emote
  await page.evaluate(() => {
    const btn = document.querySelector('.bgg-emote-btn');
    if (btn) btn.click();
  });
  await wait(600);

  const afterEmote = await page.evaluate(() => {
    const panel = document.querySelector('#emote-panel');
    const bubble = document.querySelector('.bgg-emote-bubble');
    return {
      panelClosed: panel ? getComputedStyle(panel).display === 'none' : true,
      hasBubble: !!bubble,
      bubbleText: bubble?.textContent || ''
    };
  });

  assert(afterEmote.panelClosed, 'Emote panel closes after sending');
  assert(afterEmote.hasBubble, 'Emote bubble appears');
  assert(afterEmote.bubbleText === '🎲', 'Bubble shows correct emote');

  await page.screenshot({ path: '/tmp/bg-07b-emote-sent.png' });

  // ═══════════════════════════════════════
  // TEST 8: DOUBLING CUBE UI
  // ═══════════════════════════════════════
  console.log('━━━ TEST 8: Doubling Cube ━━━');

  const cubeState = await page.evaluate(() => {
    const cubeArea = document.querySelector('#cube-area');
    const cubeBtn = document.querySelector('#btn-double');
    const doubleOffer = document.querySelector('#double-offer');
    return {
      cubeAreaExists: !!cubeArea,
      cubeBtnExists: !!cubeBtn,
      cubeBtnText: cubeBtn?.textContent?.trim() || '',
      offerPanelExists: !!doubleOffer,
      offerHidden: doubleOffer ? getComputedStyle(doubleOffer).display === 'none' : true
    };
  });

  assert(cubeState.cubeAreaExists, 'Cube area element exists');
  assert(cubeState.cubeBtnExists, 'Double button exists');
  assert(cubeState.cubeBtnText.includes('ضاعف'), 'Button text includes "ضاعف"');
  assert(cubeState.offerPanelExists, 'Double offer panel exists');
  assert(cubeState.offerHidden, 'Double offer hidden initially');

  // ═══════════════════════════════════════
  // TEST 9: QUIT / EXIT
  // ═══════════════════════════════════════
  console.log('━━━ TEST 9: Quit Game ━━━');

  await page.evaluate(() => {
    const btn = document.querySelector('#btn-quit');
    if (btn) btn.click();
  });
  await wait(1500);

  const afterQuit = await page.evaluate(() => {
    const roomWrap = document.querySelector('.bg-wrap');
    const gameContainer = document.querySelector('.bgg-container');
    return {
      backToRoom: !!roomWrap,
      gameGone: !gameContainer
    };
  });

  assert(afterQuit.backToRoom, 'Returns to room after quit');
  assert(afterQuit.gameGone, 'Game container removed');

  await page.screenshot({ path: '/tmp/bg-09-after-quit.png' });

  // ═══════════════════════════════════════
  // TEST 10: محبوسة VARIANT GAME START
  // ═══════════════════════════════════════
  console.log('━━━ TEST 10: محبوسة Variant ━━━');

  // Navigate to setup
  await page.evaluate(() => {
    const btn = document.querySelector('#btn-local');
    if (btn) btn.click();
  });
  await wait(800);

  // Select mahbousa
  await page.evaluate(() => {
    const btn = [...document.querySelectorAll('#variant-grid .bg-chip')].find(b => b.dataset.variant === 'mahbousa');
    if (btn) btn.click();
  });
  await wait(300);

  // Start game
  await page.evaluate(() => {
    const btn = document.querySelector('#btn-start');
    if (btn) btn.click();
  });
  await wait(2000);

  const mahbousaState = await page.evaluate(() => {
    const canvas = document.querySelector('#bg-canvas');
    const container = document.querySelector('.bgg-container');
    return {
      hasGame: !!container,
      hasCanvas: !!canvas,
      canvasData: canvas?.toDataURL()?.length || 0
    };
  });

  assert(mahbousaState.hasGame, 'محبوسة game starts successfully');
  assert(mahbousaState.canvasData > 5000, 'محبوسة board renders with pieces');

  await page.screenshot({ path: '/tmp/bg-10-mahbousa.png' });

  // Quit back
  await page.evaluate(() => {
    const btn = document.querySelector('#btn-quit');
    if (btn) btn.click();
  });
  await wait(1000);

  // ═══════════════════════════════════════
  // TEST 11: ٣١ VARIANT GAME START
  // ═══════════════════════════════════════
  console.log('━━━ TEST 11: ٣١ Variant ━━━');

  await page.evaluate(() => {
    const btn = document.querySelector('#btn-local');
    if (btn) btn.click();
  });
  await wait(800);

  // Select thirtyone
  await page.evaluate(() => {
    const btn = [...document.querySelectorAll('#variant-grid .bg-chip')].find(b => b.dataset.variant === 'thirtyone');
    if (btn) btn.click();
  });
  await wait(300);

  await page.evaluate(() => {
    const btn = document.querySelector('#btn-start');
    if (btn) btn.click();
  });
  await wait(2000);

  const thirtyOneState = await page.evaluate(() => {
    const canvas = document.querySelector('#bg-canvas');
    const container = document.querySelector('.bgg-container');
    return {
      hasGame: !!container,
      hasCanvas: !!canvas,
      canvasData: canvas?.toDataURL()?.length || 0
    };
  });

  assert(thirtyOneState.hasGame, '٣١ game starts successfully');
  assert(thirtyOneState.canvasData > 5000, '٣١ board renders with stacked pieces');

  await page.screenshot({ path: '/tmp/bg-11-thirtyone.png' });

  // Quit
  await page.evaluate(() => {
    const btn = document.querySelector('#btn-quit');
    if (btn) btn.click();
  });
  await wait(1000);

  // ═══════════════════════════════════════
  // TEST 12: MATCH LENGTH & CUBE OFF
  // ═══════════════════════════════════════
  console.log('━━━ TEST 12: Match Length & Cube Off ━━━');

  await page.evaluate(() => {
    const btn = document.querySelector('#btn-local');
    if (btn) btn.click();
  });
  await wait(800);

  // Set match length to 7
  await page.evaluate(() => {
    const btn = [...document.querySelectorAll('#length-grid .bg-chip')].find(b => b.dataset.len === '7');
    if (btn) btn.click();
  });
  await wait(200);

  // Turn off cube
  await page.evaluate(() => {
    const btn = [...document.querySelectorAll('#cube-grid .bg-chip')].find(b => b.dataset.cube === 'off');
    if (btn) btn.click();
  });
  await wait(200);

  // Set hard difficulty
  await page.evaluate(() => {
    const btn = [...document.querySelectorAll('#difficulty-grid .bg-chip')].find(b => b.dataset.diff === 'hard');
    if (btn) btn.click();
  });
  await wait(200);

  const setupAfter = await page.evaluate(() => {
    const lenActive = document.querySelector('#length-grid .bg-chip-active');
    const cubeActive = document.querySelector('#cube-grid .bg-chip-active');
    const diffActive = document.querySelector('#difficulty-grid .bg-chip-active');
    return {
      len: lenActive?.dataset.len,
      cube: cubeActive?.dataset.cube,
      diff: diffActive?.dataset.diff
    };
  });

  assert(setupAfter.len === '7', 'Match length set to 7');
  assert(setupAfter.cube === 'off', 'Cube set to off');
  assert(setupAfter.diff === 'hard', 'Difficulty set to hard');

  // Start with cube off
  await page.evaluate(() => {
    const btn = document.querySelector('#btn-start');
    if (btn) btn.click();
  });
  await wait(2000);

  const noCubeState = await page.evaluate(() => {
    const cubeArea = document.querySelector('#cube-area');
    return {
      cubeHidden: cubeArea ? getComputedStyle(cubeArea).display === 'none' : true
    };
  });

  assert(noCubeState.cubeHidden, 'Cube area hidden when cube disabled');

  await page.screenshot({ path: '/tmp/bg-12-no-cube.png' });

  // Quit
  await page.evaluate(() => {
    const btn = document.querySelector('#btn-quit');
    if (btn) btn.click();
  });
  await wait(1000);

  // ═══════════════════════════════════════
  // TEST 13: FULL GAME PLAY — MULTI TURNS
  // ═══════════════════════════════════════
  console.log('━━━ TEST 13: Multi-Turn Gameplay ━━━');

  // Start a fresh game with easy bot
  await page.evaluate(() => {
    const btn = document.querySelector('#btn-local');
    if (btn) btn.click();
  });
  await wait(600);

  // Set easy bot
  await page.evaluate(() => {
    const btn = [...document.querySelectorAll('#difficulty-grid .bg-chip')].find(b => b.dataset.diff === 'easy');
    if (btn) btn.click();
  });
  await wait(200);

  // Match length 1 for quick game
  await page.evaluate(() => {
    const btn = [...document.querySelectorAll('#length-grid .bg-chip')].find(b => b.dataset.len === '1');
    if (btn) btn.click();
  });
  await wait(200);

  await page.evaluate(() => {
    const btn = document.querySelector('#btn-start');
    if (btn) btn.click();
  });
  await wait(1500);

  // Play multiple turns automatically
  let turnsPlayed = 0;
  for (let t = 0; t < 10; t++) {
    // Check if roll button visible
    const canRoll = await page.evaluate(() => {
      const btn = document.querySelector('#btn-roll');
      return btn && getComputedStyle(btn).display !== 'none';
    });

    if (!canRoll) {
      // Wait for bot turn
      await wait(2000);
      continue;
    }

    // Roll
    await page.evaluate(() => {
      const btn = document.querySelector('#btn-roll');
      if (btn) btn.click();
    });
    await wait(1000);

    // Try clicking various board positions to make a move
    if (canvasRect) {
      // Try multiple positions where white pieces might be
      const positions = [
        { x: 0.62, y: 0.85 }, // point 5
        { x: 0.53, y: 0.85 }, // point 7
        { x: 0.08, y: 0.15 }, // point 12
        { x: 0.88, y: 0.15 }, // point 23
        { x: 0.7, y: 0.85 },  // point 4
        { x: 0.45, y: 0.85 }, // point 8
      ];

      for (const pos of positions) {
        await page.mouse.click(canvasRect.x + canvasRect.w * pos.x, canvasRect.y + canvasRect.h * pos.y);
        await wait(300);

        // Check if highlights appeared, then click a destination
        // Try clicking nearby positions that might be valid destinations
        const destPositions = [
          { x: pos.x - 0.08, y: pos.y },
          { x: pos.x - 0.16, y: pos.y },
          { x: pos.x + 0.08, y: pos.y },
        ];
        for (const dest of destPositions) {
          if (dest.x > 0 && dest.x < 1) {
            await page.mouse.click(canvasRect.x + canvasRect.w * dest.x, canvasRect.y + canvasRect.h * dest.y);
            await wait(200);
          }
        }
      }
    }

    turnsPlayed++;
    await wait(1500); // Wait for bot response
  }

  assert(turnsPlayed > 0, `Played ${turnsPlayed} turns without crashing`);

  // Check game is still alive (no errors crashed it)
  const gameAlive = await page.evaluate(() => {
    return !!document.querySelector('.bgg-container') || !!document.querySelector('.bg-wrap') || !!document.querySelector('.bgr-wrap');
  });
  assert(gameAlive, 'Game still renders after multi-turn play');

  await page.screenshot({ path: '/tmp/bg-13-multi-turn.png' });

  // ═══════════════════════════════════════
  // TEST 14: ONLINE BUTTON — AUTH CHECK
  // ═══════════════════════════════════════
  console.log('━━━ TEST 14: Online Auth Gate ━━━');

  // Quit current game if still in one
  await page.evaluate(() => {
    const btn = document.querySelector('#btn-quit');
    if (btn) btn.click();
  });
  await wait(1000);

  // Check the online button exists
  const onlineExists = await page.evaluate(() => {
    const btn = document.querySelector('#btn-online');
    return !!btn;
  });
  assert(onlineExists, 'Online button exists in room');

  // ═══════════════════════════════════════
  // TEST 15: CANVAS RESIZE
  // ═══════════════════════════════════════
  console.log('━━━ TEST 15: Canvas Resize ━━━');

  // Start a game, then resize viewport
  await page.evaluate(() => {
    const btn = document.querySelector('#btn-local');
    if (btn) btn.click();
  });
  await wait(500);
  await page.evaluate(() => {
    const btn = document.querySelector('#btn-start');
    if (btn) btn.click();
  });
  await wait(1500);

  // Resize to tablet
  await page.setViewport({ width: 768, height: 1024, deviceScaleFactor: 2 });
  await wait(800);

  const afterResize = await page.evaluate(() => {
    const canvas = document.querySelector('#bg-canvas');
    return {
      w: canvas?.width || 0,
      h: canvas?.height || 0,
      styleW: canvas?.style.width || '',
      styleH: canvas?.style.height || ''
    };
  });

  assert(afterResize.w > 0, `Canvas resized: ${afterResize.w}x${afterResize.h}`);
  await page.screenshot({ path: '/tmp/bg-15-resized.png' });

  // Resize to small phone
  await page.setViewport({ width: 320, height: 568, deviceScaleFactor: 2 });
  await wait(800);

  const afterSmall = await page.evaluate(() => {
    const canvas = document.querySelector('#bg-canvas');
    return { w: canvas?.width || 0, h: canvas?.height || 0 };
  });
  assert(afterSmall.w > 0 && afterSmall.w <= 400, `Small viewport canvas: ${afterSmall.w}x${afterSmall.h}`);
  await page.screenshot({ path: '/tmp/bg-15b-small.png' });

  // Reset
  await page.setViewport({ width: 390, height: 844, deviceScaleFactor: 2 });
  await wait(500);

  // ═══════════════════════════════════════
  // TEST 16: JS ERRORS CHECK
  // ═══════════════════════════════════════
  console.log('━━━ TEST 16: JS Error Check ━━━');

  const criticalErrors = jsErrors.filter(e =>
    !e.includes('net::ERR_') &&
    !e.includes('favicon') &&
    !e.includes('Failed to fetch') &&
    !e.includes('NetworkError') &&
    !e.includes('supabase')
  );

  assert(criticalErrors.length === 0, `No critical JS errors (found ${criticalErrors.length})`);
  if (criticalErrors.length > 0) {
    console.log('   Errors:');
    criticalErrors.slice(0, 5).forEach(e => console.log('     •', e.slice(0, 200)));
  }

  // ═══════════════════════════════════════
  // SUMMARY
  // ═══════════════════════════════════════
  console.log('\n═══════════════════════════════════');
  console.log(' RESULTS');
  console.log('═══════════════════════════════════\n');
  results.forEach(r => console.log(r));
  console.log(`\n  TOTAL: ${passed + failed} tests | ✓ ${passed} passed | ✗ ${failed} failed`);
  console.log('═══════════════════════════════════\n');

  if (jsErrors.length > 0) {
    console.log(`  [info] ${jsErrors.length} total console errors (including network):`);
    jsErrors.slice(0, 10).forEach(e => console.log('    •', e.slice(0, 150)));
  }

  console.log('\n  Screenshots saved to /tmp/bg-*.png');

  await browser.close();
  process.exit(failed > 0 ? 1 : 0);
}

run().catch(e => { console.error('FATAL:', e.message); process.exit(1); });
