#!/usr/bin/env node
/**
 * Production-build smoke (QA_PLAN B15). Drives the REAL built artifact — `node
 * server.js` serving dist/ — not the Vite dev server, so it validates that the
 * split vendor chunks (QA-B0-01) actually load and the app boots in production.
 *
 * Usage: node scripts/prod-smoke.js   (expects `npm run build` already run and a
 * server already listening on PROD_SMOKE_URL — the shell wrapper handles both).
 */
const { chromium } = require('@playwright/test');

const URL = process.env.PROD_SMOKE_URL || 'http://localhost:3098';
const USER = process.env.E2E_USER || 'e2e_user';
const PASS = process.env.E2E_PASS || 'e2e_pass_1234';

(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  const errors = [];
  const failed = [];
  page.on('console', (m) => { if (m.type() === 'error') errors.push(m.text()); });
  page.on('pageerror', (e) => errors.push(String(e)));
  page.on('requestfailed', (r) => failed.push(`${r.url()} ${r.failure()?.errorText || ''}`));

  let ok = true;
  const fail = (msg) => { ok = false; console.error('  ✖', msg); };

  try {
    // 1. App shell + split chunks load; login page renders.
    await page.goto(URL + '/login', { waitUntil: 'networkidle' });
    const heading = page.getByRole('heading', { name: /sign in/i });
    if (await heading.isVisible().catch(() => false)) console.log('  ✔ login page renders (vendor chunks loaded)');
    else fail('login page did not render — a chunk may have failed to load');

    // 2. Log in and reach the authenticated app (lazy route chunks load).
    await page.locator('#username').fill(USER);
    await page.locator('#password').fill(PASS);
    await page.getByRole('button', { name: /sign in/i }).click();
    await page.waitForURL((u) => !u.pathname.startsWith('/login'), { timeout: 15000 });
    const gotIt = page.getByRole('button', { name: 'Got it' });
    await gotIt.click({ timeout: 8000 }).catch(() => {});
    if (await page.getByRole('button', { name: 'Add Bill' }).isVisible().catch(() => false)) {
      console.log('  ✔ authenticated Tracker renders on the production build');
    } else fail('authenticated Tracker did not render');

    // 3. A couple of lazy-loaded routes render (their chunks resolve).
    for (const path of ['/bills', '/analytics', '/spending']) {
      await page.goto(URL + path, { waitUntil: 'networkidle' });
      const empty = await page.locator('body').innerText().catch(() => '');
      if (empty && empty.trim().length > 0) console.log(`  ✔ ${path} rendered`);
      else fail(`${path} rendered blank (lazy chunk failure?)`);
    }
  } catch (e) {
    fail('exception: ' + e.message);
  }

  const chunkErrors = failed.filter((f) => /\.js|\.css|assets/.test(f));
  if (chunkErrors.length) fail('failed asset requests:\n    ' + chunkErrors.join('\n    '));
  // The pre-login page probes /api/auth/session and gets 401 by design (then shows
  // login) — that's expected, not a defect. Everything else is a real error.
  const benign = /session check failed|Not authenticated|auth\/session|status of 401/i;
  const realErrors = errors.filter((e) => !benign.test(e));
  if (realErrors.length) fail('console/page errors:\n    ' + realErrors.slice(0, 5).join('\n    '));

  await browser.close();
  console.log(ok ? '\nPROD SMOKE: PASS' : '\nPROD SMOKE: FAIL');
  process.exit(ok ? 0 : 1);
})();
