import { chromium, Browser, Page } from '@playwright/test';
import * as fs from 'fs/promises';

export interface FormAction {
  type: 'fill' | 'click' | 'check';
  selector: string;
  value?: string;
}

export interface ScreenshotConfig {
  url: string;
  name: string;
  waitFor?: string; // CSS selector to wait for
  delay?: number; // ms to wait after page load
  actions?: FormAction[]; // Actions to perform before screenshot
}

export interface CaptureOptions {
  baseUrl: string;
  outputDir: string;
  viewport?: { width: number; height: number };
}

const DEFAULT_OPTIONS: CaptureOptions = {
  baseUrl: 'http://localhost:18188',
  outputDir: 'screenshots',
  viewport: { width: 1920, height: 1080 },
};

export async function captureScreenshots(
  screenshots: ScreenshotConfig[],
  options: Partial<CaptureOptions> = {}
): Promise<string[]> {
  const opts = { ...DEFAULT_OPTIONS, ...options };
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.setViewportSize(opts.viewport!);

  const captured: string[] = [];

  for (const config of screenshots) {
    const url = config.url.startsWith('http')
      ? config.url
      : `${opts.baseUrl}${config.url}`;

    await page.goto(url, { waitUntil: 'networkidle' });

    // Execute any form actions before screenshot
    if (config.actions) {
      for (const action of config.actions) {
        if (action.type === 'fill' && action.value) {
          await page.fill(action.selector, action.value);
        } else if (action.type === 'click') {
          await page.click(action.selector);
        } else if (action.type === 'check') {
          await page.check(action.selector);
        }
      }
    }

    if (config.waitFor) {
      await page.waitForSelector(config.waitFor, { timeout: 10000 });
    }

    if (config.delay) {
      await page.waitForTimeout(config.delay);
    }

    const path = `${opts.outputDir}/${config.name}`;
    await page.screenshot({ path, type: 'png' });
    console.log(`✓ ${config.name}`);
    captured.push(path);
  }

  await browser.close();
  return captured;
}

export async function captureSingle(
  url: string,
  name: string,
  options: Partial<CaptureOptions> = {}
): Promise<string> {
  const [path] = await captureScreenshots([{ url, name }], options);
  return path;
}

export { Browser, Page };

// CLI runner
async function main() {
  const configPath = process.argv[2];
  if (!configPath) {
    console.error('Usage: pnpm capture <config.json>');
    console.error('');
    console.error('Config format:');
    console.error(JSON.stringify({
      baseUrl: 'http://localhost:18188',
      outputDir: 'screenshots',
      screenshots: [
        { url: '/page', name: 'screenshot.png' },
        { url: '/other', name: 'other.png', waitFor: '.selector', delay: 500 },
      ],
    }, null, 2));
    process.exit(1);
  }

  const config = JSON.parse(await fs.readFile(configPath, 'utf-8'));

  // Ensure output directory exists
  await fs.mkdir(config.outputDir || 'screenshots', { recursive: true });

  await captureScreenshots(config.screenshots, {
    baseUrl: config.baseUrl,
    outputDir: config.outputDir,
  });

  console.log(`\nDone! ${config.screenshots.length} screenshots saved to ${config.outputDir || 'screenshots'}/`);
}

main();
