// a11y-check.js — Automated accessibility audit script for Foundation web properties
// Run in browser console or via Playwright/Puppeteer
//
// Usage: Paste into DevTools console, or include in automated test suite.
// Returns a JSON object with pass/fail for WCAG 2.1 AA checks.

(function a11yAudit() {
  const results = {
    timestamp: new Date().toISOString(),
    url: window.location.href,
    title: document.title,
    violations: [],
    passes: [],
    warnings: []
  };

  // --- 2.4.1 Skip Navigation ---
  const skipLink = document.querySelector('a[href="#main"], a[href="#content"], .skip-nav, .skip-link');
  if (skipLink) {
    results.passes.push({ rule: '2.4.1', name: 'Skip Navigation', detail: 'Skip link found' });
  } else {
    results.violations.push({ rule: '2.4.1', name: 'Skip Navigation', severity: 'medium', detail: 'No skip-to-content link found' });
  }

  // --- 1.3.1 / 3.3.2 Form Labels ---
  const unlabeledInputs = Array.from(document.querySelectorAll('input, select, textarea')).filter(el => {
    if (el.type === 'hidden') return false;
    const id = el.id;
    const hasLabel = id && document.querySelector(`label[for="${id}"]`);
    const hasAriaLabel = el.getAttribute('aria-label') || el.getAttribute('aria-labelledby');
    const hasTitle = el.getAttribute('title');
    const hasPlaceholder = el.getAttribute('placeholder'); // placeholder alone is NOT sufficient
    return !hasLabel && !hasAriaLabel && !hasTitle;
  });
  if (unlabeledInputs.length === 0) {
    results.passes.push({ rule: '3.3.2', name: 'Form Labels', detail: 'All inputs have labels' });
  } else {
    results.violations.push({
      rule: '3.3.2',
      name: 'Form Labels',
      severity: 'high',
      detail: `${unlabeledInputs.length} inputs without programmatic labels`,
      elements: unlabeledInputs.map(el => ({ tag: el.tagName, type: el.type, name: el.name, id: el.id }))
    });
  }

  // --- 1.4.3 Contrast (heuristic: very light text colors) ---
  const lowContrast = Array.from(document.querySelectorAll('p, span, a, li, td, th, label, small, footer *')).filter(el => {
    const style = getComputedStyle(el);
    const color = style.color;
    // Check for very light RGB values (r/g/b < 120)
    const match = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
    if (!match) return false;
    const [, r, g, b] = match.map(Number);
    return r < 120 && g < 120 && b < 120 && (r + g + b) < 200;
  });
  if (lowContrast.length === 0) {
    results.passes.push({ rule: '1.4.3', name: 'Contrast', detail: 'No obviously low-contrast text found' });
  } else {
    results.warnings.push({ rule: '1.4.3', name: 'Contrast', detail: `${lowContrast.length} elements with potentially low contrast (manual verification needed)` });
  }

  // --- 1.3.1 Heading Hierarchy ---
  const headings = Array.from(document.querySelectorAll('h1, h2, h3, h4, h5, h6')).map(h => ({
    level: parseInt(h.tagName[1]),
    text: h.textContent.trim().substring(0, 80)
  }));
  let headingIssues = [];
  let lastLevel = 0;
  for (const h of headings) {
    if (h.level > lastLevel + 1 && lastLevel > 0) {
      headingIssues.push(`Skipped h${lastLevel} to h${h.level}: "${h.text}"`);
    }
    lastLevel = h.level;
  }
  if (headingIssues.length === 0 && headings.length > 0) {
    results.passes.push({ rule: '1.3.1', name: 'Heading Hierarchy', detail: `${headings.length} headings, proper nesting` });
  } else if (headingIssues.length > 0) {
    results.violations.push({ rule: '1.3.1', name: 'Heading Hierarchy', severity: 'low', detail: headingIssues.join('; ') });
  }

  // --- 1.3.1 Landmarks ---
  const landmarks = {
    main: document.querySelectorAll('main, [role="main"]').length,
    nav: document.querySelectorAll('nav, [role="navigation"]').length,
    banner: document.querySelectorAll('header, [role="banner"]').length,
    contentinfo: document.querySelectorAll('footer, [role="contentinfo"]').length
  };
  if (landmarks.main > 0) {
    results.passes.push({ rule: '1.3.1', name: 'Main Landmark', detail: 'Found' });
  } else {
    results.violations.push({ rule: '1.3.1', name: 'Main Landmark', severity: 'medium', detail: 'No <main> or role="main" found' });
  }
  if (landmarks.banner === 0) {
    results.violations.push({ rule: '1.3.1', name: 'Banner Landmark', severity: 'low', detail: 'No <header> or role="banner" found' });
  }

  // --- 3.3.1 Required Fields ---
  const requiredInputs = document.querySelectorAll('input[required], input[aria-required="true"]');
  if (requiredInputs.length > 0) {
    results.passes.push({ rule: '3.3.1', name: 'Required Fields', detail: `${requiredInputs.length} inputs marked as required` });
  } else {
    const visualRequired = document.querySelector('.required, [class*="required"], label .text-danger');
    if (visualRequired) {
      results.warnings.push({ rule: '3.3.1', name: 'Required Fields', detail: 'Visual indicators found but no aria-required attributes' });
    }
  }

  // --- 2.4.2 Page Title ---
  if (document.title && document.title.trim().length > 0) {
    results.passes.push({ rule: '2.4.2', name: 'Page Title', detail: document.title });
  } else {
    results.violations.push({ rule: '2.4.2', name: 'Page Title', severity: 'medium', detail: 'Page has no title' });
  }

  // --- 3.1.1 Language ---
  const lang = document.documentElement.lang;
  if (lang) {
    results.passes.push({ rule: '3.1.1', name: 'Language', detail: lang });
  } else {
    results.violations.push({ rule: '3.1.1', name: 'Language', severity: 'medium', detail: 'No lang attribute on <html>' });
  }

  // --- Images without alt ---
  const imgsNoAlt = Array.from(document.querySelectorAll('img:not([alt])'));
  if (imgsNoAlt.length === 0) {
    results.passes.push({ rule: '1.1.1', name: 'Image Alt Text', detail: 'All images have alt attributes' });
  } else {
    results.violations.push({ rule: '1.1.1', name: 'Image Alt Text', severity: 'high', detail: `${imgsNoAlt.length} images without alt attributes` });
  }

  // --- Buttons without accessible names ---
  const emptyButtons = Array.from(document.querySelectorAll('button')).filter(b => {
    return !b.textContent.trim() && !b.getAttribute('aria-label') && !b.getAttribute('aria-labelledby') && !b.getAttribute('title');
  });
  if (emptyButtons.length === 0) {
    results.passes.push({ rule: '4.1.2', name: 'Button Names', detail: 'All buttons have accessible names' });
  } else {
    results.violations.push({ rule: '4.1.2', name: 'Button Names', severity: 'medium', detail: `${emptyButtons.length} buttons without accessible names` });
  }

  // Summary
  results.summary = {
    violations: results.violations.length,
    passes: results.passes.length,
    warnings: results.warnings.length
  };

  console.log(JSON.stringify(results, null, 2));
  return results;
})();
