/**
 * Screenshot capture script for the Help guides.
 *
 * Usage (run from frontend/ directory — needs frontend/node_modules/@playwright/test):
 *   cd frontend && npx tsx ../tools/capture-help-screenshots.ts
 *
 * Requires a .env.screenshots file at the repo root (see .env.screenshots.example).
 * Before running, seed test users on optical-dev:
 *   docker compose exec backend python scripts/seed_test_users.py
 */

import { chromium, type Page, type BrowserContext } from '@playwright/test';
import * as fs from 'fs';
import * as path from 'path';
import * as dotenv from 'dotenv';

// Load credentials from .env.screenshots
dotenv.config({ path: path.join(__dirname, '../.env.screenshots') });

const BASE_URL = process.env.BASE_URL || 'https://optical-dev.oliver.solutions/video-accessibility';
const OUT_DIR = path.join(__dirname, '../frontend/public/help-screenshots');

// Ensure output directories exist
const ROLES = ['global', 'client', 'linguist', 'reviewer', 'production', 'project-manager', 'admin'];
for (const role of ROLES) {
  fs.mkdirSync(path.join(OUT_DIR, role), { recursive: true });
}

interface AnnotationRect {
  x: number;
  y: number;
  width: number;
  height: number;
  label?: string;
}

async function annotateAndScreenshot(
  page: Page,
  outputPath: string,
  annotations: AnnotationRect[] = []
) {
  if (annotations.length > 0) {
    // Inject red rectangles as overlay divs
    await page.evaluate((rects) => {
      for (const rect of rects) {
        const div = document.createElement('div');
        div.style.cssText = `
          position: fixed;
          left: ${rect.x}px;
          top: ${rect.y}px;
          width: ${rect.width}px;
          height: ${rect.height}px;
          border: 3px solid #EF4444;
          border-radius: 4px;
          z-index: 99999;
          pointer-events: none;
          box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.3);
        `;
        if (rect.label) {
          const label = document.createElement('span');
          label.textContent = rect.label;
          label.style.cssText = `
            position: absolute;
            top: -22px;
            left: 0;
            background: #EF4444;
            color: white;
            font-size: 11px;
            font-weight: bold;
            padding: 2px 6px;
            border-radius: 3px;
            white-space: nowrap;
            font-family: system-ui, sans-serif;
          `;
          div.appendChild(label);
        }
        document.body.appendChild(div);
      }
    }, annotations);
  }

  await page.screenshot({ path: outputPath, fullPage: false });

  // Clean up overlays
  if (annotations.length > 0) {
    await page.evaluate(() => {
      document.querySelectorAll('[data-annotation-overlay]').forEach(el => el.remove());
    });
  }

  console.log(`  ✓ ${path.relative(OUT_DIR, outputPath)}`);
}

async function getBBox(page: Page, selector: string): Promise<AnnotationRect | null> {
  const el = page.locator(selector).first();
  try {
    const bb = await el.boundingBox({ timeout: 3000 });
    if (!bb) return null;
    return { x: bb.x, y: bb.y, width: bb.width, height: bb.height };
  } catch {
    return null;
  }
}

async function login(page: Page, email: string, password: string) {
  await page.goto(`${BASE_URL}/login`);
  await page.waitForLoadState('networkidle');

  // The login page defaults to Microsoft SSO view.
  // Click "Local login" to reveal the email/password form.
  try {
    const toggle = page.getByRole('button', { name: /local login/i });
    await toggle.click({ timeout: 3000 });
    await page.waitForSelector('input[type="email"]', { timeout: 3000 });
  } catch {
    // Toggle absent (form already visible or different build) — proceed
  }

  await page.fill('input[type="email"]', email);
  await page.fill('input[type="password"]', password);
  await page.click('button[type="submit"]');
  await page.waitForURL(url => !url.toString().includes('/login'), { timeout: 10000 });
  await page.waitForLoadState('networkidle');
}

async function captureGlobal(context: BrowserContext) {
  console.log('\n📸 Global screenshots...');
  const page = await context.newPage();

  // 01 — Login screen
  await page.goto(`${BASE_URL}/login`);
  await page.waitForLoadState('networkidle');
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'global/01-login.png'));

  // 02 — Email field highlighted
  const emailBB = await getBBox(page, 'input[type="email"]');
  if (emailBB) {
    await annotateAndScreenshot(page, path.join(OUT_DIR, 'global/02-login-email.png'), [
      { ...emailBB, label: 'Left-click here to type email' }
    ]);
  }

  // Login as test-admin to capture authenticated global screenshots
  await login(page, process.env.TEST_ADMIN_EMAIL!, process.env.TEST_ADMIN_PASSWORD!);

  // 03 — Interface overview
  await page.goto(`${BASE_URL}/`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'global/04-interface-overview.png'));

  // 04 — Sidebar
  const sidebarBB = await getBBox(page, 'nav');
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'global/05-sidebar.png'));

  // 05 — Navbar
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'global/06-navbar.png'));

  // 06 — Notifications (click bell)
  const bell = page.locator('button[aria-label*="notification"], button:has-text("🔔")').first();
  try {
    await bell.click({ timeout: 3000 });
    await page.waitForTimeout(300);
    await annotateAndScreenshot(page, path.join(OUT_DIR, 'global/07-notifications.png'));
    await page.keyboard.press('Escape');
  } catch {
    // Bell might not exist or be differently structured
  }

  await page.close();
}

async function captureClient(context: BrowserContext) {
  console.log('\n📸 Client screenshots...');
  const page = await context.newPage();
  await login(page, process.env.TEST_CLIENT_EMAIL!, process.env.TEST_CLIENT_PASSWORD!);

  // Dashboard
  await page.goto(`${BASE_URL}/`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'client/01-dashboard.png'));

  // New Job page
  await page.goto(`${BASE_URL}/jobs/new`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'client/02-new-job.png'));

  // Drop zone
  const dropzoneBB = await getBBox(page, '[data-testid="upload-dropzone"], .dropzone, input[type="file"]');
  if (dropzoneBB) {
    await annotateAndScreenshot(page, path.join(OUT_DIR, 'client/03-upload-dropzone.png'), [
      { ...dropzoneBB, label: 'Drag file here or left-click to browse' }
    ]);
  }

  // Jobs list
  await page.goto(`${BASE_URL}/jobs`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'client/12-jobs-list.png'));

  // Briefs list
  await page.goto(`${BASE_URL}/briefs`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'client/16-new-brief.png'));

  await page.close();
}

async function captureLinguist(context: BrowserContext) {
  console.log('\n📸 Linguist screenshots...');
  const page = await context.newPage();
  await login(page, process.env.TEST_LINGUIST_EMAIL!, process.env.TEST_LINGUIST_PASSWORD!);

  // Dashboard
  await page.goto(`${BASE_URL}/`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'linguist/01-dashboard.png'));

  // QC Queue
  await page.goto(`${BASE_URL}/qc/queue`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'linguist/02-qc-queue.png'));

  await page.close();
}

async function captureReviewer(context: BrowserContext) {
  console.log('\n📸 Reviewer screenshots...');
  const page = await context.newPage();
  await login(page, process.env.TEST_REVIEWER_EMAIL!, process.env.TEST_REVIEWER_PASSWORD!);

  await page.goto(`${BASE_URL}/`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'reviewer/01-dashboard.png'));

  await page.goto(`${BASE_URL}/qc/queue`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'reviewer/02-qc-queue.png'));

  await page.goto(`${BASE_URL}/qc/reviewer-queue`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'reviewer/03-reviewer-queue.png'));

  await page.goto(`${BASE_URL}/admin/final`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'reviewer/08-final-list.png'));

  await page.close();
}

async function captureProduction(context: BrowserContext) {
  console.log('\n📸 Production screenshots...');
  const page = await context.newPage();
  await login(page, process.env.TEST_PRODUCTION_EMAIL!, process.env.TEST_PRODUCTION_PASSWORD!);

  await page.goto(`${BASE_URL}/`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'production/01-dashboard.png'));

  await page.goto(`${BASE_URL}/jobs`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'production/02-jobs-list-bulk.png'));

  await page.goto(`${BASE_URL}/admin/failures`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'production/05-failures.png'));

  await page.goto(`${BASE_URL}/admin/audit-log`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'production/06-audit-log.png'));

  await page.close();
}

async function captureProjectManager(context: BrowserContext) {
  console.log('\n📸 Project Manager screenshots...');
  const page = await context.newPage();
  await login(page, process.env.TEST_PM_EMAIL!, process.env.TEST_PM_PASSWORD!);

  await page.goto(`${BASE_URL}/`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'project-manager/01-dashboard.png'));

  await page.goto(`${BASE_URL}/admin/final`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'project-manager/02-final-list.png'));

  await page.goto(`${BASE_URL}/admin/clients`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'project-manager/05-clients.png'));

  await page.close();
}

async function captureAdmin(context: BrowserContext) {
  console.log('\n📸 Admin screenshots...');
  const page = await context.newPage();
  await login(page, process.env.TEST_ADMIN_EMAIL!, process.env.TEST_ADMIN_PASSWORD!);

  await page.goto(`${BASE_URL}/`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'admin/01-dashboard.png'));

  // User Management
  await page.goto(`${BASE_URL}/admin/users`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await annotateAndScreenshot(page, path.join(OUT_DIR, 'admin/02-user-list.png'));

  // Create User modal
  const createBtn = page.getByRole('button', { name: /create user/i });
  try {
    await createBtn.click({ timeout: 3000 });
    await page.waitForTimeout(400);
    await annotateAndScreenshot(page, path.join(OUT_DIR, 'admin/03-create-user-modal.png'));
    await page.keyboard.press('Escape');
  } catch { /* modal may not have opened */ }

  await page.close();
}

async function main() {
  console.log('🚀 Capturing help screenshots...');
  console.log(`   Target: ${BASE_URL}`);
  console.log(`   Output: ${OUT_DIR}\n`);

  const browser = await chromium.launch({ headless: true });
  const context = await browser.newContext({
    viewport: { width: 1440, height: 900 },
    deviceScaleFactor: 1,
  });

  try {
    await captureGlobal(context);
    await captureClient(context);
    await captureLinguist(context);
    await captureReviewer(context);
    await captureProduction(context);
    await captureProjectManager(context);
    await captureAdmin(context);
  } finally {
    await context.close();
    await browser.close();
  }

  console.log('\n✅ All screenshots captured!');
}

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