/**
 * Shared proofshot helper for Playwright.
 *
 * Basic usage:
 *   import { captureProofshots } from './proofshots';
 *   captureProofshots('/persons', 'persons');
 *
 * With per-test setup (e.g. seed localStorage before navigation):
 *   captureProofshots('/persons', 'persons', {
 *     setup: async (page) => {
 *       await page.goto('/persons/some-id'); // populates any localStorage state
 *     }
 *   });
 *
 * The setup callback runs before each screenshot's page.goto(url), so any
 * localStorage values it writes persist into the main navigation.
 *
 * Screenshots are saved to proofshot-artifacts/{featureName}/.
 */
import { type Page, test } from '@playwright/test';
import path from 'path';
import fs from 'fs';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

const viewports = [
	{ name: 'mobile', width: 390, height: 844 },
	{ name: 'tablet', width: 768, height: 1024 },
	{ name: 'desktop', width: 1440, height: 900 }
];

interface ProofshotOptions {
	/**
	 * Optional async callback that runs before each screenshot's page.goto(url).
	 * Use it to seed localStorage, visit a prerequisite page, etc.
	 */
	setup?: (page: Page) => Promise<void>;
}

/**
 * Registers Playwright tests that navigate to `url`, apply each theme,
 * and capture full-page screenshots at all standard viewports.
 *
 * @param url         The path to screenshot (e.g. '/', '/persons', '/admin')
 * @param featureName Used as the output directory name and screenshot file prefix
 * @param options     Optional setup callback and other options
 */
export function captureProofshots(
	url: string,
	featureName: string,
	options?: ProofshotOptions
): void {
	const outDir = path.join(__dirname, '../../proofshot-artifacts', featureName);
	fs.mkdirSync(outDir, { recursive: true });

	for (const vp of viewports) {
		for (const theme of ['light', 'dark'] as const) {
			test(`${featureName} – ${vp.name} – ${theme}`, async ({ page }) => {
				// Run optional setup before main navigation (e.g. seed localStorage)
				if (options?.setup) {
					await options.setup(page);
				}

				await page.setViewportSize({ width: vp.width, height: vp.height });
				await page.goto(url);

				// Apply theme via data-theme attribute and localStorage
				await page.evaluate((t) => {
					document.documentElement.setAttribute('data-theme', t);
					localStorage.setItem('theme', t);
				}, theme);

				// 'networkidle' is unreliable in SvelteKit dev mode due to the HMR WebSocket.
				await page.waitForLoadState('domcontentloaded');
				await page.waitForSelector('main', { state: 'visible' });

				await page.screenshot({
					path: path.join(outDir, `${featureName}-${vp.name}-${theme}.png`),
					fullPage: true
				});
			});
		}
	}
}
