// Self-eval screenshot harness. Boots vite preview, drives window.__game, captures vantages.
// Uses ONE page per viewport (WebGL ctx + bundle load is the slow part on swiftshader).
import { chromium } from 'playwright';
import { spawn } from 'node:child_process';
import { mkdirSync } from 'node:fs';

const PORT = 4173;
const SEED = process.env.SEED || '7';
const URL = `http://127.0.0.1:${PORT}/?auto&debug&seed=${SEED}`;
const OUT = 'shots';
mkdirSync(OUT, { recursive: true });

function waitFor(re, proc, timeout = 20000) {
  return new Promise((res, rej) => {
    const to = setTimeout(() => rej(new Error('server timeout')), timeout);
    const on = (d) => { if (re.test(d.toString())) { clearTimeout(to); res(); } };
    proc.stdout.on('data', on); proc.stderr.on('data', on);
  });
}

const server = spawn('npm', ['run', 'preview'], { stdio: ['ignore', 'pipe', 'pipe'] });
await waitFor(/4173/, server);
await new Promise((r) => setTimeout(r, 600));

const browser = await chromium.launch({
  args: ['--use-gl=angle', '--use-angle=swiftshader', '--ignore-gpu-blocklist', '--enable-webgl', '--enable-unsafe-swapchain'],
});
const errors = [];
const sleep = (p, ms) => p.waitForTimeout(ms);

async function newPage(viewport, extra = {}) {
  const page = await browser.newPage({ viewport, deviceScaleFactor: 1, ...extra });
  page.on('console', (m) => { if (m.type() === 'error') errors.push(m.text()); });
  page.on('pageerror', (e) => errors.push('PAGEERROR ' + e.message));
  await page.goto(URL, { waitUntil: 'load' });
  await page.waitForFunction(() => !!window.__game, { timeout: 15000 });
  await sleep(page, 400);
  return page;
}
async function snap(page, name) {
  try { await page.screenshot({ path: `${OUT}/${name}.png`, timeout: 60000, animations: 'allow' }); console.log('shot', name); }
  catch (e) { console.log('SNAP FAIL', name, e.message); }
}

try {
  const page = await newPage({ width: 1600, height: 900 });
  await page.evaluate(() => window.__game.start());
  await sleep(page, 600);

  // 1. space view
  await page.evaluate(() => window.__game._spaceShot(0));
  await sleep(page, 900);
  await snap(page, '1-space');

  // 2. entry (frozen mid-descent: speed lines + sky blend + lit planet)
  await page.evaluate(() => window.__game._entry(0, 0.72));
  await sleep(page, 900);
  await snap(page, '2-entry');

  // 3. surface vista with flora + parked ship
  await page.evaluate(() => window.__game.teleportPlanet(0));
  await sleep(page, 1100);
  await page.evaluate(() => window.__game._faceShip());
  await sleep(page, 900);
  await snap(page, '3-surface');

  // 4. scanner pulse + nameplates (face the field so plates land in frame)
  await page.evaluate(() => window.__game._faceShip());
  await sleep(page, 200);
  await page.evaluate(() => window.__game._scanShot());
  await sleep(page, 500);
  console.log('PLATES', await page.evaluate(() => window.__game._plates));
  await snap(page, '4-scan');

  // 5. second planet (contrast)
  await page.evaluate(() => window.__game.teleportPlanet(1));
  await sleep(page, 1100);
  await page.evaluate(() => window.__game._faceShip());
  await sleep(page, 900);
  await snap(page, '5-planet2');

  // diagnostics
  await sleep(page, 800);
  const diag = await page.evaluate(() => ({
    phase: window.__game.phase, mode: window.__game.mode, planet: window.__game.planet,
    units: window.__game.units, scans: window.__game.scans, resources: window.__game.resources,
    info: window.__rinfo,
  }));
  console.log('DIAG', JSON.stringify(diag));
  await page.close();

  // win screen (verify full loop completes)
  const w = await newPage({ width: 1600, height: 900 });
  await w.evaluate(() => window.__game.teleportPlanet(0));
  await sleep(w, 900);
  await w.evaluate(() => { window.__game._scanShot(); window.__game._grantGoal(); window.__game.takeoff(); });
  await sleep(w, 600);
  await w.evaluate(() => window.__game.teleportPlanet(1));
  await sleep(w, 3200);
  console.log('WIN', await w.evaluate(() => window.__game.phase));
  await snap(w, '6-win');
  await w.close();

  // mobile (emulate touch so on-screen controls render)
  const m = await newPage({ width: 412, height: 915 }, { hasTouch: true, isMobile: true });
  await m.evaluate(() => window.__game.teleportPlanet(0));
  await sleep(m, 1100);
  await m.evaluate(() => window.__game._faceShip());
  await sleep(m, 800);
  await snap(m, 'm-surface');
  await m.evaluate(() => window.__game.start && window.__game._spaceShot(0));
  await sleep(m, 800);
  await snap(m, 'm-space');
  await m.close();
} catch (e) {
  console.error('HARNESS ERROR', e.message);
} finally {
  console.log('CONSOLE_ERRORS', JSON.stringify([...new Set(errors)].slice(0, 12)));
  await browser.close();
  server.kill('SIGTERM');
  setTimeout(() => process.exit(0), 400);
}
