// shots/smoke.mjs — drive the LIVE game loop to catch runtime errors the
// frozen screenshot presets don't exercise (flight, entry, FP walk, scan, mine, win).
import { chromium } from 'playwright';

const URL = process.env.GAME_URL || 'http://localhost:5173/';
const errors = [];
const wf = (page, n) => page.evaluate((c) => new Promise((res) => {
  let i = 0; const t = () => (++i >= c ? res(true) : requestAnimationFrame(t)); requestAnimationFrame(t);
}), n);
const state = (page) => page.evaluate(() => ({
  mode: window.__game.mode, phase: window.__game.phase,
  units: window.__game.units, scans: window.__game.scans, resources: window.__game.resources,
}));

const browser = await chromium.launch({ headless: true, args: ['--use-gl=angle', '--use-angle=swiftshader', '--enable-unsafe-swiftshader', '--disable-dev-shm-usage'] });
const page = await browser.newPage({ viewport: { width: 1280, height: 720 } });
page.on('console', (m) => { if (m.type() === 'error') errors.push('CONSOLE: ' + m.text()); });
page.on('pageerror', (e) => errors.push('PAGEERROR: ' + e.message));
await page.goto(URL, { waitUntil: 'networkidle' });
await page.waitForFunction(() => !!window.__game, null, { timeout: 20000 });
await wf(page, 20);

const log = (label, s) => console.log(label.padEnd(22), JSON.stringify(s));

// 1) land on planet 0 (instant) and walk + scan
await page.evaluate(() => window.__game.teleportPlanet(0));
await page.evaluate(() => window.__game.unfreeze());
await page.keyboard.down('KeyW'); await wf(page, 24); await page.keyboard.up('KeyW');
await page.keyboard.down('Space'); await wf(page, 4); await page.keyboard.up('Space');
await page.keyboard.press('KeyC'); await wf(page, 70);
log('after walk+scan', await state(page));

// 2) mine: aim at nearest crystal, hold LMB
const aimed = await page.evaluate(() => window.__game.aimCrystal());
const beforeMine = await state(page);
await page.mouse.down(); await wf(page, 90); await page.mouse.up();
const afterMine = await state(page);
log(`mine aimed=${aimed}`, { before: beforeMine.resources, after: afterMine.resources, units: afterMine.units });

// 3) take off -> live flight
await page.evaluate(() => window.__game.takeoff());
await page.keyboard.down('KeyW'); await page.keyboard.down('ShiftLeft'); await wf(page, 40);
await page.keyboard.up('ShiftLeft'); await page.keyboard.up('KeyW');
log('after flight', await state(page));

// 4) land via the live entry sequence
await page.evaluate(() => window.__game.land());
let landed = false;
for (let i = 0; i < 12; i++) { await wf(page, 25); if ((await state(page)).mode === 'surface') { landed = true; break; } }
log(`live entry landed=${landed}`, await state(page));

// 5) win: force progress + visit a 2nd planet
await page.evaluate(() => { window.__game.forceProgress(); window.__game.teleportPlanet(1); });
await wf(page, 30); await new Promise((r) => setTimeout(r, 2200)); await wf(page, 10);
log('after win trigger', await state(page));

console.log('\nerrors:', errors.length);
for (const e of errors.slice(0, 30)) console.log(' ', e);
await browser.close();
console.log(errors.length ? 'SMOKE: FAIL' : 'SMOKE: PASS');
