/**
 * Theme switching visual regression — captures dark + light screenshots of key pages.
 *
 * Run from web/ directory after starting backend (port 8000) + dev server (port 5173):
 *   node test/theme-screenshots.mjs
 *
 * Output: ../docs/screenshots/<page>__<theme>.png
 */
import { chromium } from '@playwright/test';
import { mkdir } from 'node:fs/promises';
import { resolve, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const OUT_DIR = resolve(__dirname, '../../docs/screenshots');
const BASE = 'http://localhost:5173';
const API = 'http://localhost:8000';

const ADMIN = { username: 'admin', password: 'admin123' };
const TEAM_USER = { username: 'screenshot_user', password: 'shotpass123' };

/** Set theme directly via localStorage + html attribute, no UI click needed. */
async function setTheme(page, theme) {
  await page.evaluate((t) => {
    localStorage.setItem('airdrama-theme', t);
    document.documentElement.dataset.theme = t;
  }, theme);
  // Reload to ensure ECharts and any once-mounted styles re-init
  await page.reload({ waitUntil: 'domcontentloaded' });
  await page.waitForTimeout(400);
}

/** Programmatic login: POST to API → seed tokens into localStorage → navigate. */
async function login(page, creds) {
  const res = await page.request.post(`${API}/api/v1/auth/login`, { data: creds });
  if (!res.ok()) throw new Error(`login ${creds.username} failed: ${res.status()} ${await res.text()}`);
  const body = await res.json();
  const access = body?.tokens?.access;
  const refresh = body?.tokens?.refresh;
  const user = body?.user;
  if (!access) throw new Error(`login ${creds.username}: no access token in response`);
  await page.goto(`${BASE}/login`, { waitUntil: 'domcontentloaded' });
  await page.evaluate(({ access, refresh, user }) => {
    localStorage.setItem('access_token', access);
    if (refresh) localStorage.setItem('refresh_token', refresh);
    if (user) localStorage.setItem('user', JSON.stringify(user));
  }, { access, refresh, user });
}

async function shot(page, slug, theme) {
  const file = resolve(OUT_DIR, `${slug}__${theme}.png`);
  await page.screenshot({ path: file, fullPage: false });
  console.log(`  ✓ ${slug}__${theme}.png`);
}

/** Visit URL, wait for network idle + a settle timeout, then screenshot in both themes. */
async function visitAndCapture(page, slug, url, opts = {}) {
  for (const theme of ['dark', 'light']) {
    await setTheme(page, theme);
    await page.goto(`${BASE}${url}`, { waitUntil: 'domcontentloaded' }).catch(() => {});
    await page.waitForTimeout(opts.settle ?? 800);
    if (opts.afterLoad) await opts.afterLoad(page);
    await shot(page, slug, theme);
  }
}

async function main() {
  await mkdir(OUT_DIR, { recursive: true });

  const browser = await chromium.launch({ headless: true });
  const ctx = await browser.newContext({
    viewport: { width: 1440, height: 900 },
    deviceScaleFactor: 1,
  });
  const page = await ctx.newPage();
  // Mute console errors (API 4xx/5xx in empty DB are noisy but expected)
  page.on('pageerror', () => {});
  page.on('console', () => {});

  console.log(`▼ Capturing to ${OUT_DIR}`);

  // 1. Login page (no auth needed) — use a fresh context so localStorage is clean
  console.log('\n[1/12] /login');
  for (const theme of ['dark', 'light']) {
    await page.goto(`${BASE}/login`, { waitUntil: 'domcontentloaded' });
    await setTheme(page, theme);
    await page.waitForTimeout(500);
    await shot(page, '01_login', theme);
  }

  // 2. Login as admin → admin pages
  console.log('\n[2/12] admin login');
  await login(page, ADMIN);

  await visitAndCapture(page, '02_admin_dashboard', '/admin/dashboard', { settle: 1500 });
  console.log('[3/12] /admin/dashboard');

  await visitAndCapture(page, '03_admin_users', '/admin/users');
  console.log('[4/12] /admin/users');

  await visitAndCapture(page, '04_admin_records', '/admin/records');
  console.log('[5/12] /admin/records');

  await visitAndCapture(page, '05_admin_settings', '/admin/settings');
  console.log('[6/12] /admin/settings');

  await visitAndCapture(page, '06_admin_security', '/admin/security');
  console.log('[7/12] /admin/security');

  await visitAndCapture(page, '07_admin_logs', '/admin/logs');
  console.log('[8/12] /admin/logs');

  await visitAndCapture(page, '08_admin_assets', '/admin/assets');
  console.log('[9/12] /admin/assets');

  // 3. Switch to team_admin user → generation + profile + team pages
  console.log('\n[10/12] team_user login');
  await ctx.clearCookies();
  await page.evaluate(() => localStorage.clear());
  await login(page, TEAM_USER);

  await visitAndCapture(page, '09_generation', '/app', { settle: 1200 });
  console.log('[10/12] /app');

  await visitAndCapture(page, '10_profile', '/profile', { settle: 1200 });
  console.log('[11/12] /profile');

  await visitAndCapture(page, '11_team_dashboard', '/team/dashboard', { settle: 1500 });
  console.log('[12/12] /team/dashboard');

  await visitAndCapture(page, '12_team_members', '/team/members');
  console.log('[12/12] /team/members');

  await browser.close();
  console.log('\n✅ done');
}

main().catch((err) => {
  console.error('❌ screenshot run failed:', err);
  process.exit(1);
});
