/**
 * WCAG 2.1 AAA compliance test using axe-core
 * 
 * This test runs axe-core against all pages of the website to check for WCAG 2.1 AAA compliance.
 * It tests for issues related to:
 * - Color contrast (7:1 ratio for AAA)
 * - Text spacing
 * - Heading structure
 * - ARIA attributes
 * - And many other WCAG 2.1 AAA criteria
 */

const { chromium } = require('playwright');
const axeCore = require('axe-core');
const fs = require('fs');
const path = require('path');

// URLs to test
const BASE_URL = process.argv[2] || 'http://localhost:8080'\;
const PAGES = [
  '/',
  '/stories/',
  '/stories/open-source-success.html',
  '/stories/viperwire.html',
  '/one-pager-tools/csv-tool.html'
];

// Create reports directory if it doesn't exist
const reportsDir = path.join(__dirname, '../reports');
if (!fs.existsSync(reportsDir)) {
  fs.mkdirSync(reportsDir, { recursive: true });
}

async function runAxe(page, pagePath) {
  // Inject axe-core into the page
  await page.evaluate(() => {
    if (!window.axe) {
      // This would normally be done by injecting the axe-core script
      // but for this example, we'll assume axe-core is already available
      console.log('Warning: axe-core not available in the page');
    }
  });

  // Run axe with WCAG 2.1 AAA rules
  const results = await page.evaluate(() => {
    return new Promise(resolve => {
      if (!window.axe) {
        resolve({ error: 'axe-core not available' });
        return;
      }
      
      axe.run(document, { 
        runOnly: { 
          type: 'tag', 
          values: ['wcag2aaa'] 
        },
        resultTypes: ['violations', 'incomplete', 'inapplicable'],
        rules: {
          'color-contrast': { enabled: true, options: { noScroll: true } }
        }
      })
      .then(results => resolve(results))
      .catch(err => resolve({ error: err.toString() }));
    });
  });

  return results;
}

async function testPage(browser, pageUrl) {
  const page = await browser.newPage();
  console.log(`Testing ${pageUrl}...`);
  
  try {
    // Navigate to the page
    await page.goto(pageUrl, { waitUntil: 'networkidle' });
    
    // Run axe-core tests
    const results = await runAxe(page, pageUrl);
    
    // Save results to file
    const fileName = pageUrl === BASE_URL ? 'index' : pageUrl.replace(BASE_URL, '').replace(/\//g, '-').replace(/^-/, '');
    const reportPath = path.join(reportsDir, `axe-${fileName || 'index'}.json`);
    fs.writeFileSync(reportPath, JSON.stringify(results, null, 2));
    
    // Log results summary
    if (results.error) {
      console.error(`Error running axe-core on ${pageUrl}:`, results.error);
      return { url: pageUrl, success: false, error: results.error };
    }
    
    const { violations, incomplete, passes, inapplicable } = results;
    console.log(`Results for ${pageUrl}:`);
    console.log(`- Violations: ${violations.length}`);
    console.log(`- Incomplete: ${incomplete.length}`);
    console.log(`- Passes: ${passes.length}`);
    console.log(`- Inapplicable: ${inapplicable.length}`);
    
    // Print violations
    if (violations.length > 0) {
      console.log('\nViolations:');
      violations.forEach((violation, i) => {
        console.log(`${i + 1}. ${violation.id} - ${violation.help} (Impact: ${violation.impact})`);
        console.log(`   ${violation.description}`);
        console.log(`   WCAG: ${violation.tags.filter(t => t.startsWith('wcag')).join(', ')}`);
        console.log(`   Elements: ${violation.nodes.length}`);
      });
    }
    
    return { 
      url: pageUrl, 
      success: violations.length === 0, 
      violations: violations.length,
      incomplete: incomplete.length,
      passes: passes.length
    };
  } catch (error) {
    console.error(`Error testing ${pageUrl}:`, error);
    return { url: pageUrl, success: false, error: error.toString() };
  } finally {
    await page.close();
  }
}

async function runTests() {
  const browser = await chromium.launch();
  const results = [];
  
  try {
    // Test each page
    for (const pagePath of PAGES) {
      const pageUrl = `${BASE_URL}${pagePath}`;
      const result = await testPage(browser, pageUrl);
      results.push(result);
    }
    
    // Save overall results
    const overallReport = {
      timestamp: new Date().toISOString(),
      baseUrl: BASE_URL,
      pages: results,
      summary: {
        total: results.length,
        passed: results.filter(r => r.success).length,
        failed: results.filter(r => !r.success).length
      }
    };
    
    fs.writeFileSync(path.join(reportsDir, 'axe-summary.json'), JSON.stringify(overallReport, null, 2));
    
    // Print overall summary
    console.log('\n=== Overall Summary ===');
    console.log(`Total pages tested: ${overallReport.summary.total}`);
    console.log(`Pages passed: ${overallReport.summary.passed}`);
    console.log(`Pages failed: ${overallReport.summary.failed}`);
    
    // Exit with appropriate code
    process.exit(overallReport.summary.failed > 0 ? 1 : 0);
  } catch (error) {
    console.error('Error running tests:', error);
    process.exit(1);
  } finally {
    await browser.close();
  }
}

runTests();
