/**
 * Accessibility Tests
 * Tests for screen reader compatibility and keyboard navigation
 */

const { test, expect } = require('playwright/test');

test.describe('Research Form Accessibility', () => {
    test.beforeEach(async ({ page }) => {
        // Navigate to the research page
        await page.goto('/research/');

        // Wait for the page to load completely
        await page.waitForLoadState('networkidle');
    });

    test('mode selection should have proper radio button structure', async ({ page }) => {
        // Check that radio buttons exist and are properly structured
        const radioButtons = await page.locator('input[name="research_mode"]');
        await expect(radioButtons).toHaveCount(2);

        // Check that each radio button has a proper ID and label
        const quickRadio = await page.locator('#mode-quick');
        const detailedRadio = await page.locator('#mode-detailed');

        await expect(quickRadio).toBeVisible();
        await expect(detailedRadio).toBeVisible();

        // Check that labels are properly associated
        const quickLabel = await page.locator('label[for="mode-quick"]');
        const detailedLabel = await page.locator('label[for="mode-detailed"]');

        await expect(quickLabel).toBeVisible();
        await expect(detailedLabel).toBeVisible();

        // Check default selection
        await expect(quickRadio).toBeChecked();
        await expect(detailedRadio).not.toBeChecked();
    });

    test('mode selection should be accessible via keyboard', async ({ page }) => {
        const quickLabel = await page.locator('label[for="mode-quick"]');
        const detailedLabel = await page.locator('label[for="mode-detailed"]');

        // Focus on quick mode first
        await quickLabel.focus();

        // Check initial state
        await expect(quickLabel).toBeFocused();
        await expect(await page.locator('#mode-quick')).toBeChecked();

        // Navigate to detailed mode with arrow keys
        await page.keyboard.press('ArrowRight');
        await expect(detailedLabel).toBeFocused();
        await expect(await page.locator('#mode-detailed')).toBeChecked();

        // Navigate back with arrow keys
        await page.keyboard.press('ArrowLeft');
        await expect(quickLabel).toBeFocused();
        await expect(await page.locator('#mode-quick')).toBeChecked();
    });

    test('mode selection should respond to Enter and Space keys', async ({ page }) => {
        const detailedLabel = await page.locator('label[for="mode-detailed"]');

        // Focus on detailed mode
        await detailedLabel.focus();

        // Press Enter to select
        await page.keyboard.press('Enter');
        await expect(await page.locator('#mode-detailed')).toBeChecked();

        // Focus back to quick mode and test Space key
        const quickLabel = await page.locator('label[for="mode-quick"]');
        await quickLabel.focus();
        await page.keyboard.press('Space');
        await expect(await page.locator('#mode-quick')).toBeChecked();
    });

    test('fieldset and legend should be properly structured', async ({ page }) => {
        // Check for fieldset and legend elements
        const fieldset = await page.locator('fieldset');
        const legend = await page.locator('legend');

        await expect(fieldset).toBeVisible();
        await expect(legend).toBeVisible();
        await expect(legend).toHaveText('Research Mode');

        // Check that radiogroup role is present
        const radioGroup = await page.locator('[role="radiogroup"]');
        await expect(radioGroup).toBeVisible();
    });

    test('keyboard shortcuts should work in textarea', async ({ page }) => {
        const textarea = await page.locator('#query');

        // Focus on textarea
        await textarea.focus();

        // Type some text
        await textarea.fill('Test research query');

        // Test Shift+Enter for new line
        await page.keyboard.press('Shift+Enter');
        await textarea.type('Second line');

        // Check that text contains newline
        const textValue = await textarea.inputValue();
        expect(textValue).toContain('\n');
        expect(textValue).toContain('Test research query');
        expect(textValue).toContain('Second line');
    });

    test('Enter key should submit form from textarea', async ({ page }) => {
        const textarea = await page.locator('#query');
        const startButton = await page.locator('#start-research-btn');

        // Focus on textarea
        await textarea.focus();
        await textarea.fill('Test query for submission');

        // Mock the form submission to avoid actual API call
        await page.route('/research/api/start_research', (route) => {
            route.fulfill({
                status: 200,
                contentType: 'application/json',
                body: JSON.stringify({ status: 'success', research_id: 'test-123' })
            });
        });

        // Press Enter to submit
        await page.keyboard.press('Enter');

        // Check that button shows loading state
        await expect(startButton).toHaveText(/Starting.../);
    });

    test('keyboard hints should be visible', async ({ page }) => {
        const keyboardHint = await page.locator('.keyboard-hint');
        const hintText = await page.locator('.hint-text');

        await expect(keyboardHint).toBeVisible();
        await expect(hintText).toBeVisible();
        await expect(hintText).toHaveText('Press Enter to search • Shift+Enter for new line');
    });

    test('ARIA attributes should be properly set', async ({ page }) => {
        // Check ARIA attributes on mode options
        const quickLabel = await page.locator('label[for="mode-quick"]');
        const detailedLabel = await page.locator('label[for="mode-detailed"]');

        // Check role attributes
        await expect(quickLabel).toHaveAttribute('role', 'radio');
        await expect(detailedLabel).toHaveAttribute('role', 'radio');

        // Check aria-checked attributes
        await expect(quickLabel).toHaveAttribute('aria-checked', 'true');
        await expect(detailedLabel).toHaveAttribute('aria-checked', 'false');

        // Check tabindex attributes
        await expect(quickLabel).toHaveAttribute('tabindex', '0');
        await expect(detailedLabel).toHaveAttribute('tabindex', '-1');

        // Check that icons have aria-hidden
        const icons = await page.locator('.mode-icon i');
        for (let i = 0; i < await icons.count(); i++) {
            await expect(icons.nth(i)).toHaveAttribute('aria-hidden', 'true');
        }
    });

    test('mode selection should update radio buttons correctly', async ({ page }) => {
        const detailedLabel = await page.locator('label[for="mode-detailed"]');
        const detailedRadio = await page.locator('#mode-detailed');
        const quickRadio = await page.locator('#mode-quick');

        // Click on detailed mode
        await detailedLabel.click();

        // Check that radio button state is updated
        await expect(detailedRadio).toBeChecked();
        await expect(quickRadio).not.toBeChecked();

        // Check visual state is updated
        await expect(detailedLabel).toHaveClass(/active/);
        await expect(detailedLabel).toHaveAttribute('aria-checked', 'true');
    });

    test('form should be navigable with Tab key', async ({ page }) => {
        // Start from textarea
        const textarea = await page.locator('#query');
        await textarea.focus();

        // Tab to mode selection
        await page.keyboard.press('Tab');
        const quickLabel = await page.locator('label[for="mode-quick"]');
        await expect(quickLabel).toBeFocused();

        // Tab through advanced options toggle
        await page.keyboard.press('Tab');
        const advancedToggle = await page.locator('.advanced-options-toggle');
        await expect(advancedToggle).toBeFocused();

        // Tab to notification toggle
        await page.keyboard.press('Tab');
        const notificationToggle = await page.locator('#notification-toggle');
        await expect(notificationToggle).toBeFocused();

        // Tab to submit button
        await page.keyboard.press('Tab');
        const submitButton = await page.locator('#start-research-btn');
        await expect(submitButton).toBeFocused();
    });

    test('screen reader only elements should be properly hidden', async ({ page }) => {
        const radioButtons = await page.locator('input[name="research_mode"]');

        // Check that radio buttons have sr-only class
        for (let i = 0; i < await radioButtons.count(); i++) {
            await expect(radioButtons.nth(i)).toHaveClass(/sr-only/);
        }

        // Check that sr-only elements are visually hidden but accessible
        const srOnlyStyle = await page.evaluate(() => {
            const element = document.querySelector('.sr-only');
            return window.getComputedStyle(element);
        });

        expect(srOnlyStyle.position).toBe('absolute');
        expect(srOnlyStyle.width).toBe('1px');
        expect(srOnlyStyle.height).toBe('1px');
    });

    test('form submission should use radio button values', async ({ page }) => {
        const detailedLabel = await page.locator('label[for="mode-detailed"]');

        // Select detailed mode
        await detailedLabel.click();

        // Fill in required fields
        await page.locator('#query').fill('Test query');

        // Mock the API to capture the form data
        let capturedData = null;
        await page.route('/research/api/start_research', (route) => {
            capturedData = JSON.parse(route.request().postData());
            route.fulfill({
                status: 200,
                contentType: 'application/json',
                body: JSON.stringify({ status: 'success', research_id: 'test-123' })
            });
        });

        // Submit the form
        await page.locator('#start-research-btn').click();

        // Wait for the API call
        await page.waitForTimeout(1000);

        // Check that the correct mode was sent
        expect(capturedData.mode).toBe('detailed');
    });
});

test.describe('Accessibility Compliance', () => {
    test('page should not have accessibility violations', async ({ page }) => {
        await page.goto('/research/');
        await page.waitForLoadState('networkidle');

        // Inject axe-core for accessibility testing (from node_modules)
        await page.addScriptTag({
            path: require.resolve('axe-core/axe.min.js')
        });

        // Run accessibility scan
        const results = await page.evaluate(() => {
            return new Promise((resolve) => {
                axe.run({
                    rules: {
                        // Focus on WCAG 2.1 AA standards
                        'color-contrast': { enabled: true },
                        'keyboard-navigation': { enabled: true },
                        'focus-management': { enabled: true },
                        'aria-usage': { enabled: true }
                    }
                }, (err, results) => {
                    resolve(results);
                });
            });
        });

        // Check for violations
        if (results.violations.length > 0) {
            console.log('Accessibility violations found:');
            results.violations.forEach(violation => {
                console.log(`- ${violation.id}: ${violation.description}`);
                violation.nodes.forEach(node => {
                    console.log(`  Target: ${node.target}`);
                });
            });
        }

        // Expect no critical violations
        const criticalViolations = results.violations.filter(v =>
            v.impact === 'critical' || v.impact === 'serious'
        );
        expect(criticalViolations).toHaveLength(0);
    });

    test('focus should be visible and logical', async ({ page }) => {
        await page.goto('/research/');

        // Test that focus is visible on all interactive elements
        const interactiveElements = [
            '#query',
            'label[for="mode-quick"]',
            'label[for="mode-detailed"]',
            '.advanced-options-toggle',
            '#notification-toggle',
            '#start-research-btn'
        ];

        for (const selector of interactiveElements) {
            await page.locator(selector).focus();

            // Check that focus is visible (outline or box-shadow)
            const element = await page.locator(selector);
            const styles = await element.evaluate(el => {
                const computed = window.getComputedStyle(el);
                return {
                    outline: computed.outline,
                    boxShadow: computed.boxShadow,
                    outlineOffset: computed.outlineOffset
                };
            });

            // Should have either outline or box-shadow for focus
            const hasFocusStyle = styles.outline !== 'none' ||
                                styles.boxShadow !== 'none' ||
                                styles.outlineOffset !== '0px';

            expect(hasFocusStyle).toBe(true);
        }
    });
});
