import { test } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
import * as fs from 'fs';
import * as path from 'path';

test.describe('Manual Accessibility Audit - Authentication Pages', () => {
  test('comprehensive accessibility audit with detailed reporting', async ({ page }) => {
    const report = {
      timestamp: new Date().toISOString(),
      pages: [] as any[],
    };

    const pagesToTest = [
      { url: 'http://localhost:9000/en/login', name: 'Login Page (English)' },
      { url: 'http://localhost:9000/en/signup', name: 'Signup Page (English)' },
      { url: 'http://localhost:9000/ar/login', name: 'Login Page (Arabic/RTL)' },
      { url: 'http://localhost:9000/ar/signup', name: 'Signup Page (Arabic/RTL)' },
    ];

    for (const pageInfo of pagesToTest) {
      console.log(`\n${'='.repeat(60)}`);
      console.log(`Testing: ${pageInfo.name}`);
      console.log(`URL: ${pageInfo.url}`);
      console.log('='.repeat(60));

      await page.goto(pageInfo.url);

      // Run axe accessibility scan
      const results = await new AxeBuilder({ page })
        .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
        .analyze();

      // Collect page information
      const pageData = {
        name: pageInfo.name,
        url: pageInfo.url,
        language: await page.locator('html').getAttribute('lang'),
        direction: await page.locator('html').getAttribute('dir'),
        violations: results.violations.map((v) => ({
          id: v.id,
          impact: v.impact,
          description: v.description,
          help: v.help,
          helpUrl: v.helpUrl,
          nodes: v.nodes.length,
          tags: v.tags,
        })),
        passes: results.passes.length,
        incomplete: results.incomplete.map((i) => ({
          id: i.id,
          description: i.description,
        })),
        formAnalysis: {} as any,
        keyboardNavigation: {} as any,
        headingStructure: [] as any[],
        ariaUsage: {} as any,
      };

      // Form analysis
      console.log('\n--- FORM ANALYSIS ---');
      const inputs = await page.locator('input:not([type="hidden"])').all();
      const formIssues = [];

      for (const input of inputs) {
        const id = await input.getAttribute('id');
        const name = await input.getAttribute('name');
        const type = await input.getAttribute('type');
        const ariaLabel = await input.getAttribute('aria-label');
        const ariaLabelledby = await input.getAttribute('aria-labelledby');
        const ariaDescribedby = await input.getAttribute('aria-describedby');
        const ariaRequired = await input.getAttribute('aria-required');
        const required = await input.getAttribute('required');
        const autocomplete = await input.getAttribute('autocomplete');
        const label = await page.locator(`label[for="${id}"]`).count();

        const hasLabel = ariaLabel || ariaLabelledby || label > 0;

        const inputInfo = {
          name: name || type,
          type,
          hasLabel,
          hasAriaLabel: !!ariaLabel,
          hasAriaLabelledby: !!ariaLabelledby,
          hasAriaDescribedby: !!ariaDescribedby,
          isRequired: !!(required || ariaRequired === 'true'),
          hasAutocomplete: !!autocomplete,
        };

        console.log(`Input: ${inputInfo.name} (${inputInfo.type})`);
        console.log(`  ✓ Label: ${hasLabel ? 'YES' : 'NO'}`);
        console.log(`  ✓ Required: ${inputInfo.isRequired ? 'YES' : 'NO'}`);
        console.log(`  ✓ Autocomplete: ${autocomplete || 'NONE'}`);

        if (!hasLabel) {
          formIssues.push(`Input "${inputInfo.name}" missing label`);
        }
      }

      pageData.formAnalysis = {
        totalInputs: inputs.length,
        inputsWithLabels: inputs.length - formIssues.length,
        issues: formIssues,
      };

      // Heading structure
      console.log('\n--- HEADING STRUCTURE ---');
      const headings = await page.locator('h1, h2, h3, h4, h5, h6').all();
      const headingStructure = [];

      for (const heading of headings) {
        const text = await heading.textContent();
        const level = await heading.evaluate((el) => el.tagName);
        headingStructure.push({ level, text: text?.trim() });
        console.log(`${level}: ${text?.trim()}`);
      }

      pageData.headingStructure = headingStructure;

      // Keyboard navigation test
      console.log('\n--- KEYBOARD NAVIGATION ---');
      const tabOrder = [];

      for (let i = 0; i < 20; i++) {
        await page.keyboard.press('Tab');
        const focused = await page.evaluate(() => {
          const el = document.activeElement;
          return {
            tag: el?.tagName,
            name: el?.getAttribute('name') || el?.getAttribute('aria-label') || el?.textContent?.trim().substring(0, 30),
            type: el?.getAttribute('type'),
            hasVisibleFocus: (() => {
              const style = window.getComputedStyle(el as Element);
              return (
                (style.outlineWidth !== '0px' && style.outlineStyle !== 'none') ||
                style.boxShadow !== 'none'
              );
            })(),
          };
        });

        if (focused.name) {
          tabOrder.push(focused);
          console.log(`Tab ${i + 1}: ${focused.tag} - ${focused.name} (Focus: ${focused.hasVisibleFocus ? '✓' : '✗'})`);
        }
      }

      pageData.keyboardNavigation = {
        tabStops: tabOrder.length,
        elementsWithoutVisibleFocus: tabOrder.filter((t) => !t.hasVisibleFocus).length,
      };

      // ARIA usage
      console.log('\n--- ARIA USAGE ---');
      const ariaElements = {
        ariaLabel: await page.locator('[aria-label]').count(),
        ariaLabelledby: await page.locator('[aria-labelledby]').count(),
        ariaDescribedby: await page.locator('[aria-describedby]').count(),
        ariaRequired: await page.locator('[aria-required]').count(),
        ariaInvalid: await page.locator('[aria-invalid]').count(),
        ariaLive: await page.locator('[aria-live]').count(),
        role: await page.locator('[role]').count(),
      };

      console.log(`aria-label: ${ariaElements.ariaLabel}`);
      console.log(`aria-labelledby: ${ariaElements.ariaLabelledby}`);
      console.log(`aria-describedby: ${ariaElements.ariaDescribedby}`);
      console.log(`aria-required: ${ariaElements.ariaRequired}`);
      console.log(`role attributes: ${ariaElements.role}`);

      pageData.ariaUsage = ariaElements;

      // Violations summary
      console.log('\n--- VIOLATIONS SUMMARY ---');
      if (results.violations.length === 0) {
        console.log('✅ No WCAG 2.1 AA violations found!');
      } else {
        console.log(`❌ Found ${results.violations.length} violations:`);
        results.violations.forEach((v, idx) => {
          console.log(`\n${idx + 1}. ${v.id} (Impact: ${v.impact})`);
          console.log(`   ${v.description}`);
          console.log(`   Help: ${v.helpUrl}`);
          console.log(`   Affected nodes: ${v.nodes.length}`);
        });
      }

      // Incomplete checks
      if (results.incomplete.length > 0) {
        console.log('\n--- INCOMPLETE CHECKS (Manual review needed) ---');
        results.incomplete.forEach((item) => {
          console.log(`- ${item.id}: ${item.description}`);
        });
      }

      report.pages.push(pageData);
    }

    // Generate summary report
    console.log('\n\n' + '='.repeat(60));
    console.log('ACCESSIBILITY AUDIT SUMMARY');
    console.log('='.repeat(60));

    const totalViolations = report.pages.reduce((sum, p) => sum + p.violations.length, 0);
    const totalPasses = report.pages.reduce((sum, p) => sum + p.passes, 0);

    console.log(`\nTotal pages tested: ${report.pages.length}`);
    console.log(`Total violations: ${totalViolations}`);
    console.log(`Total passes: ${totalPasses}`);

    report.pages.forEach((pageData) => {
      console.log(`\n${pageData.name}:`);
      console.log(`  Violations: ${pageData.violations.length}`);
      console.log(`  Passes: ${pageData.passes}`);
      console.log(`  Form inputs: ${pageData.formAnalysis.totalInputs} (${pageData.formAnalysis.inputsWithLabels} labeled)`);
      console.log(`  Keyboard tab stops: ${pageData.keyboardNavigation.tabStops}`);
      console.log(`  Headings: ${pageData.headingStructure.length}`);
    });

    // Save report to file
    const reportPath = path.join(__dirname, '../../accessibility-report.json');
    fs.writeFileSync(reportPath, JSON.stringify(report, null, 2));
    console.log(`\n✅ Full report saved to: ${reportPath}`);

    // Create human-readable report
    const readableReportPath = path.join(__dirname, '../../accessibility-report.md');
    let markdown = `# Accessibility Test Report\n\n`;
    markdown += `**Generated:** ${report.timestamp}\n\n`;
    markdown += `## Summary\n\n`;
    markdown += `- **Pages Tested:** ${report.pages.length}\n`;
    markdown += `- **Total Violations:** ${totalViolations}\n`;
    markdown += `- **Total Passes:** ${totalPasses}\n\n`;

    report.pages.forEach((pageData) => {
      markdown += `## ${pageData.name}\n\n`;
      markdown += `**URL:** ${pageData.url}\n`;
      markdown += `**Language:** ${pageData.language} (${pageData.direction})\n\n`;

      markdown += `### WCAG 2.1 AA Compliance\n\n`;
      if (pageData.violations.length === 0) {
        markdown += `✅ **No violations found**\n\n`;
      } else {
        markdown += `❌ **${pageData.violations.length} violations found**\n\n`;
        pageData.violations.forEach((v: any, idx: number) => {
          markdown += `${idx + 1}. **${v.id}** (Impact: ${v.impact})\n`;
          markdown += `   - ${v.description}\n`;
          markdown += `   - [Help](${v.helpUrl})\n`;
          markdown += `   - Affected elements: ${v.nodes}\n\n`;
        });
      }

      markdown += `### Form Accessibility\n\n`;
      markdown += `- Total inputs: ${pageData.formAnalysis.totalInputs}\n`;
      markdown += `- Inputs with labels: ${pageData.formAnalysis.inputsWithLabels}\n`;
      if (pageData.formAnalysis.issues.length > 0) {
        markdown += `- Issues:\n`;
        pageData.formAnalysis.issues.forEach((issue: string) => {
          markdown += `  - ${issue}\n`;
        });
      }
      markdown += `\n`;

      markdown += `### Keyboard Navigation\n\n`;
      markdown += `- Tab stops: ${pageData.keyboardNavigation.tabStops}\n`;
      markdown += `- Elements without visible focus: ${pageData.keyboardNavigation.elementsWithoutVisibleFocus}\n\n`;

      markdown += `### Heading Structure\n\n`;
      pageData.headingStructure.forEach((h: any) => {
        markdown += `- **${h.level}:** ${h.text}\n`;
      });
      markdown += `\n`;

      markdown += `### ARIA Usage\n\n`;
      markdown += `- aria-label: ${pageData.ariaUsage.ariaLabel}\n`;
      markdown += `- aria-labelledby: ${pageData.ariaUsage.ariaLabelledby}\n`;
      markdown += `- aria-describedby: ${pageData.ariaUsage.ariaDescribedby}\n`;
      markdown += `- aria-required: ${pageData.ariaUsage.ariaRequired}\n`;
      markdown += `- role attributes: ${pageData.ariaUsage.role}\n\n`;
    });

    markdown += `## Recommendations\n\n`;
    if (totalViolations === 0) {
      markdown += `✅ All pages meet WCAG 2.1 Level AA standards. Continue monitoring for regressions.\n\n`;
    } else {
      markdown += `Priority fixes needed:\n\n`;
      report.pages.forEach((pageData) => {
        if (pageData.violations.length > 0) {
          markdown += `### ${pageData.name}\n\n`;
          pageData.violations.forEach((v: any) => {
            markdown += `- Fix **${v.id}** (Impact: ${v.impact})\n`;
          });
          markdown += `\n`;
        }
      });
    }

    fs.writeFileSync(readableReportPath, markdown);
    console.log(`✅ Readable report saved to: ${readableReportPath}`);
  });
});
