import { appendFileSync, mkdirSync, writeFileSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import type { Page, TestInfo } from '@playwright/test';

function safeName(value: string) {
  return value.replace(/[^a-zA-Z0-9._-]+/g, '_');
}

function evidenceRoot(testInfo: TestInfo) {
  const explicitRoot = process.env.EVIDENCE_ROOT?.trim();
  if (explicitRoot) {
    return resolve(explicitRoot);
  }

  return resolve(testInfo.project.outputDir, '..', 'evidence');
}

export async function captureEvidence(page: Page, testInfo: TestInfo, label: string) {
  const root = evidenceRoot(testInfo);
  const stem = safeName(`${testInfo.file}-${testInfo.title}-${label}`);
  const screenshotPath = resolve(root, `${stem}.png`);
  const domPath = resolve(root, `${stem}.html`);
  const urlPath = resolve(root, `${stem}.url.txt`);
  const manifestPath = resolve(root, `manifest.jsonl`);

  mkdirSync(dirname(screenshotPath), { recursive: true });

  await page.screenshot({ path: screenshotPath, fullPage: true });
  writeFileSync(domPath, await page.content(), 'utf8');
  writeFileSync(urlPath, page.url(), 'utf8');
  appendFileSync(manifestPath, JSON.stringify({
    testFile: testInfo.file,
    title: testInfo.title,
    label,
    url: page.url(),
    screenshotPath,
    domPath,
    urlPath,
    timestamp: new Date().toISOString()
  }) + '\n', 'utf8');

  await testInfo.attach(`screenshot:${label}`, { path: screenshotPath, contentType: 'image/png' });
  await testInfo.attach(`dom:${label}`, { path: domPath, contentType: 'text/html' });
  await testInfo.attach(`url:${label}`, { path: urlPath, contentType: 'text/plain' });

  return { screenshotPath, domPath, urlPath };
}
