/**
 * PrismaOS Website Accessibility Enhancements
 * Provides comprehensive accessibility features including:
 * - High contrast mode
 * - Font size adjustment
 * - Motion reduction
 * - Keyboard navigation
 * - Screen reader support
 */

class AccessibilityManager {
    constructor() {
        this.settings = {
            fontSize: 'normal',
            highContrast: false,
            reducedMotion: false,
            enhancedFocus: false
        };
        
        this.init();
    }

    init() {
        this.loadSettings();
        this.setupEventListeners();
        this.setupKeyboardNavigation();
        this.applySettings();
        this.announceToScreenReader('Accessibility features loaded');
    }

    setupEventListeners() {
        // Font size controls
        const increaseFontBtn = document.getElementById('increase-font');
        const decreaseFontBtn = document.getElementById('decrease-font');
        
        if (increaseFontBtn) {
            increaseFontBtn.addEventListener('click', () => this.adjustFontSize('increase'));
        }
        
        if (decreaseFontBtn) {
            decreaseFontBtn.addEventListener('click', () => this.adjustFontSize('decrease'));
        }

        // High contrast toggle
        const highContrastBtn = document.getElementById('high-contrast');
        if (highContrastBtn) {
            highContrastBtn.addEventListener('click', () => this.toggleHighContrast());
        }

        // Motion reduction toggle
        const reduceMotionBtn = document.getElementById('reduce-motion');
        if (reduceMotionBtn) {
            reduceMotionBtn.addEventListener('click', () => this.toggleReducedMotion());
        }

        // Enhanced focus for keyboard users
        document.addEventListener('keydown', (e) => {
            if (e.key === 'Tab') {
                this.enableEnhancedFocus();
            }
        });

        // Disable enhanced focus on mouse use
        document.addEventListener('mousedown', () => {
            this.disableEnhancedFocus();
        });

        // Escape key to close modals and return focus
        document.addEventListener('keydown', (e) => {
            if (e.key === 'Escape') {
                this.handleEscapeKey();
            }
        });
    }

    adjustFontSize(direction) {
        const body = document.body;
        const currentSize = this.settings.fontSize;
        
        let newSize;
        if (direction === 'increase') {
            switch (currentSize) {
                case 'normal':
                    newSize = 'large';
                    break;
                case 'large':
                    newSize = 'xl';
                    break;
                default:
                    newSize = 'xl';
            }
        } else {
            switch (currentSize) {
                case 'xl':
                    newSize = 'large';
                    break;
                case 'large':
                    newSize = 'normal';
                    break;
                default:
                    newSize = 'normal';
            }
        }

        // Remove existing font size classes
        body.classList.remove('large-text', 'xl-text');
        
        // Apply new font size
        if (newSize === 'large') {
            body.classList.add('large-text');
        } else if (newSize === 'xl') {
            body.classList.add('xl-text');
        }

        this.settings.fontSize = newSize;
        this.saveSettings();
        
        // Announce change to screen readers
        const announcement = `Font size changed to ${newSize}`;
        this.announceToScreenReader(announcement);
    }

    toggleHighContrast() {
        const body = document.body;
        const isHighContrast = !this.settings.highContrast;
        
        if (isHighContrast) {
            body.classList.add('high-contrast');
        } else {
            body.classList.remove('high-contrast');
        }

        this.settings.highContrast = isHighContrast;
        this.saveSettings();
        
        // Update button text and announcement
        const btn = document.getElementById('high-contrast');
        if (btn) {
            btn.setAttribute('aria-pressed', isHighContrast.toString());
        }
        
        const announcement = isHighContrast ? 'High contrast mode enabled' : 'High contrast mode disabled';
        this.announceToScreenReader(announcement);
    }

    toggleReducedMotion() {
        const body = document.body;
        const isReducedMotion = !this.settings.reducedMotion;
        
        if (isReducedMotion) {
            body.classList.add('reduce-motion');
        } else {
            body.classList.remove('reduce-motion');
        }

        this.settings.reducedMotion = isReducedMotion;
        this.saveSettings();
        
        // Update button text and announcement
        const btn = document.getElementById('reduce-motion');
        if (btn) {
            btn.setAttribute('aria-pressed', isReducedMotion.toString());
        }
        
        const announcement = isReducedMotion ? 'Motion reduction enabled' : 'Motion reduction disabled';
        this.announceToScreenReader(announcement);
    }

    enableEnhancedFocus() {
        if (!this.settings.enhancedFocus) {
            document.body.classList.add('enhanced-focus');
            this.settings.enhancedFocus = true;
        }
    }

    disableEnhancedFocus() {
        document.body.classList.remove('enhanced-focus');
        this.settings.enhancedFocus = false;
    }

    setupKeyboardNavigation() {
        // Handle roving tabindex for complex widgets
        const tabLists = document.querySelectorAll('[role="tablist"]');
        tabLists.forEach(tabList => this.setupRovingTabindex(tabList));

        // Handle accordion keyboard navigation
        const accordions = document.querySelectorAll('.accordion');
        accordions.forEach(accordion => this.setupAccordionNavigation(accordion));

        // Handle custom dropdown navigation
        const dropdowns = document.querySelectorAll('.dropdown');
        dropdowns.forEach(dropdown => this.setupDropdownNavigation(dropdown));
    }

    setupRovingTabindex(tabList) {
        const tabs = tabList.querySelectorAll('[role="tab"]');
        let currentIndex = 0;

        // Set initial tabindex
        tabs.forEach((tab, index) => {
            tab.setAttribute('tabindex', index === 0 ? '0' : '-1');
        });

        tabList.addEventListener('keydown', (e) => {
            let newIndex = currentIndex;

            switch (e.key) {
                case 'ArrowRight':
                case 'ArrowDown':
                    e.preventDefault();
                    newIndex = (currentIndex + 1) % tabs.length;
                    break;
                case 'ArrowLeft':
                case 'ArrowUp':
                    e.preventDefault();
                    newIndex = (currentIndex - 1 + tabs.length) % tabs.length;
                    break;
                case 'Home':
                    e.preventDefault();
                    newIndex = 0;
                    break;
                case 'End':
                    e.preventDefault();
                    newIndex = tabs.length - 1;
                    break;
                default:
                    return;
            }

            // Update tabindex and focus
            tabs[currentIndex].setAttribute('tabindex', '-1');
            tabs[newIndex].setAttribute('tabindex', '0');
            tabs[newIndex].focus();
            currentIndex = newIndex;
        });
    }

    setupAccordionNavigation(accordion) {
        const headers = accordion.querySelectorAll('.accordion-button');
        
        headers.forEach(header => {
            header.addEventListener('keydown', (e) => {
                switch (e.key) {
                    case 'ArrowDown':
                        e.preventDefault();
                        this.focusNextAccordionHeader(header, headers);
                        break;
                    case 'ArrowUp':
                        e.preventDefault();
                        this.focusPrevAccordionHeader(header, headers);
                        break;
                    case 'Home':
                        e.preventDefault();
                        headers[0].focus();
                        break;
                    case 'End':
                        e.preventDefault();
                        headers[headers.length - 1].focus();
                        break;
                }
            });
        });
    }

    focusNextAccordionHeader(current, headers) {
        const currentIndex = Array.from(headers).indexOf(current);
        const nextIndex = (currentIndex + 1) % headers.length;
        headers[nextIndex].focus();
    }

    focusPrevAccordionHeader(current, headers) {
        const currentIndex = Array.from(headers).indexOf(current);
        const prevIndex = (currentIndex - 1 + headers.length) % headers.length;
        headers[prevIndex].focus();
    }

    setupDropdownNavigation(dropdown) {
        const trigger = dropdown.querySelector('.dropdown-toggle');
        const menu = dropdown.querySelector('.dropdown-menu');
        const items = menu ? menu.querySelectorAll('.dropdown-item') : [];

        if (!trigger || !menu || items.length === 0) return;

        trigger.addEventListener('keydown', (e) => {
            switch (e.key) {
                case 'ArrowDown':
                case 'Enter':
                case ' ':
                    e.preventDefault();
                    menu.classList.add('show');
                    items[0].focus();
                    break;
            }
        });

        items.forEach((item, index) => {
            item.addEventListener('keydown', (e) => {
                switch (e.key) {
                    case 'ArrowDown':
                        e.preventDefault();
                        const nextIndex = (index + 1) % items.length;
                        items[nextIndex].focus();
                        break;
                    case 'ArrowUp':
                        e.preventDefault();
                        const prevIndex = (index - 1 + items.length) % items.length;
                        items[prevIndex].focus();
                        break;
                    case 'Escape':
                        e.preventDefault();
                        menu.classList.remove('show');
                        trigger.focus();
                        break;
                    case 'Home':
                        e.preventDefault();
                        items[0].focus();
                        break;
                    case 'End':
                        e.preventDefault();
                        items[items.length - 1].focus();
                        break;
                }
            });
        });
    }

    handleEscapeKey() {
        // Close any open modals
        const openModals = document.querySelectorAll('.modal.show');
        openModals.forEach(modal => {
            const bsModal = bootstrap.Modal.getInstance(modal);
            if (bsModal) {
                bsModal.hide();
            }
        });

        // Close any open dropdowns
        const openDropdowns = document.querySelectorAll('.dropdown-menu.show');
        openDropdowns.forEach(dropdown => {
            dropdown.classList.remove('show');
        });

        // Close any open collapses
        const openCollapses = document.querySelectorAll('.collapse.show');
        openCollapses.forEach(collapse => {
            const bsCollapse = bootstrap.Collapse.getInstance(collapse);
            if (bsCollapse) {
                bsCollapse.hide();
            }
        });
    }

    announceToScreenReader(message) {
        // Create a live region for screen reader announcements
        let liveRegion = document.getElementById('accessibility-announcements');
        
        if (!liveRegion) {
            liveRegion = document.createElement('div');
            liveRegion.id = 'accessibility-announcements';
            liveRegion.setAttribute('aria-live', 'polite');
            liveRegion.setAttribute('aria-atomic', 'true');
            liveRegion.className = 'sr-only';
            document.body.appendChild(liveRegion);
        }

        // Clear previous message and set new one
        liveRegion.textContent = '';
        setTimeout(() => {
            liveRegion.textContent = message;
        }, 100);

        // Clear the message after it's been announced
        setTimeout(() => {
            liveRegion.textContent = '';
        }, 3000);
    }

    loadSettings() {
        try {
            const saved = localStorage.getItem('prismaos-accessibility-settings');
            if (saved) {
                this.settings = { ...this.settings, ...JSON.parse(saved) };
            }
        } catch (e) {
            console.warn('Could not load accessibility settings:', e);
        }

        // Also check for system preferences
        if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
            this.settings.reducedMotion = true;
        }

        if (window.matchMedia && window.matchMedia('(prefers-contrast: high)').matches) {
            this.settings.highContrast = true;
        }
    }

    saveSettings() {
        try {
            localStorage.setItem('prismaos-accessibility-settings', JSON.stringify(this.settings));
        } catch (e) {
            console.warn('Could not save accessibility settings:', e);
        }
    }

    applySettings() {
        const body = document.body;

        // Apply font size
        if (this.settings.fontSize === 'large') {
            body.classList.add('large-text');
        } else if (this.settings.fontSize === 'xl') {
            body.classList.add('xl-text');
        }

        // Apply high contrast
        if (this.settings.highContrast) {
            body.classList.add('high-contrast');
        }

        // Apply reduced motion
        if (this.settings.reducedMotion) {
            body.classList.add('reduce-motion');
        }

        // Update button states
        const highContrastBtn = document.getElementById('high-contrast');
        if (highContrastBtn) {
            highContrastBtn.setAttribute('aria-pressed', this.settings.highContrast.toString());
        }

        const reduceMotionBtn = document.getElementById('reduce-motion');
        if (reduceMotionBtn) {
            reduceMotionBtn.setAttribute('aria-pressed', this.settings.reducedMotion.toString());
        }
    }

    // Method to handle focus management for single page apps
    manageFocus(targetElement) {
        if (targetElement) {
            targetElement.setAttribute('tabindex', '-1');
            targetElement.focus();
            targetElement.addEventListener('blur', function removeFocusManagement() {
                targetElement.removeAttribute('tabindex');
                targetElement.removeEventListener('blur', removeFocusManagement);
            });
        }
    }

    // Method to trap focus within a container (useful for modals)
    trapFocus(container) {
        const focusableElements = container.querySelectorAll(
            'a[href], button, textarea, input[type="text"], input[type="radio"], input[type="checkbox"], select, [tabindex]:not([tabindex="-1"])'
        );
        
        if (focusableElements.length === 0) return;

        const firstFocusable = focusableElements[0];
        const lastFocusable = focusableElements[focusableElements.length - 1];

        function handleTabKey(e) {
            if (e.key === 'Tab') {
                if (e.shiftKey) {
                    if (document.activeElement === firstFocusable) {
                        e.preventDefault();
                        lastFocusable.focus();
                    }
                } else {
                    if (document.activeElement === lastFocusable) {
                        e.preventDefault();
                        firstFocusable.focus();
                    }
                }
            }
        }

        container.addEventListener('keydown', handleTabKey);
        return () => container.removeEventListener('keydown', handleTabKey);
    }
}

// Enhanced Text-to-Speech functionality
class TextToSpeechManager {
    constructor() {
        this.synthesis = window.speechSynthesis;
        this.voices = [];
        this.isSupported = 'speechSynthesis' in window;
        this.currentUtterance = null;
        
        if (this.isSupported) {
            this.loadVoices();
        }
    }

    loadVoices() {
        this.voices = this.synthesis.getVoices();
        
        // Sometimes voices load asynchronously
        if (this.voices.length === 0) {
            this.synthesis.addEventListener('voiceschanged', () => {
                this.voices = this.synthesis.getVoices();
            });
        }
    }

    speak(text, options = {}) {
        if (!this.isSupported) {
            console.warn('Text-to-speech not supported in this browser');
            return Promise.reject(new Error('TTS not supported'));
        }

        // Stop any current speech
        this.stop();

        return new Promise((resolve, reject) => {
            const utterance = new SpeechSynthesisUtterance(text);
            
            // Set voice preferences
            const preferredVoice = this.voices.find(voice => 
                voice.lang.startsWith(options.language || 'en') && 
                voice.name.toLowerCase().includes('female')
            ) || this.voices.find(voice => voice.lang.startsWith(options.language || 'en')) || this.voices[0];
            
            if (preferredVoice) {
                utterance.voice = preferredVoice;
            }

            utterance.rate = options.rate || 1.0;
            utterance.pitch = options.pitch || 1.0;
            utterance.volume = options.volume || 1.0;

            utterance.onstart = () => {
                if (options.onStart) options.onStart();
            };

            utterance.onend = () => {
                this.currentUtterance = null;
                if (options.onEnd) options.onEnd();
                resolve();
            };

            utterance.onerror = (event) => {
                this.currentUtterance = null;
                if (options.onError) options.onError(event);
                reject(event);
            };

            this.currentUtterance = utterance;
            this.synthesis.speak(utterance);
        });
    }

    stop() {
        if (this.isSupported && this.synthesis.speaking) {
            this.synthesis.cancel();
            this.currentUtterance = null;
        }
    }

    pause() {
        if (this.isSupported && this.synthesis.speaking) {
            this.synthesis.pause();
        }
    }

    resume() {
        if (this.isSupported && this.synthesis.paused) {
            this.synthesis.resume();
        }
    }

    isSpeaking() {
        return this.isSupported && this.synthesis.speaking;
    }

    getVoices() {
        return this.voices;
    }
}

// Initialize accessibility when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
    // Initialize accessibility manager
    window.accessibilityManager = new AccessibilityManager();
    
    // Initialize TTS manager
    window.ttsManager = new TextToSpeechManager();
    
    // Add aria-current to active navigation items
    const currentPath = window.location.pathname;
    const navLinks = document.querySelectorAll('.nav-link');
    navLinks.forEach(link => {
        if (link.getAttribute('href') === currentPath) {
            link.setAttribute('aria-current', 'page');
        }
    });
    
    // Improve form accessibility
    const forms = document.querySelectorAll('form');
    forms.forEach(form => {
        const requiredFields = form.querySelectorAll('[required]');
        requiredFields.forEach(field => {
            field.setAttribute('aria-required', 'true');
        });
    });
    
    // Add live region for dynamic content updates
    if (!document.getElementById('live-region')) {
        const liveRegion = document.createElement('div');
        liveRegion.id = 'live-region';
        liveRegion.setAttribute('aria-live', 'polite');
        liveRegion.setAttribute('aria-atomic', 'false');
        liveRegion.className = 'sr-only';
        document.body.appendChild(liveRegion);
    }
});

// Export for use in other scripts
if (typeof module !== 'undefined' && module.exports) {
    module.exports = { AccessibilityManager, TextToSpeechManager };
}
