/**
 * PrismaOS Website Main JavaScript
 * Handles interactive features, demos, and general website functionality
 */

class PrismaOSWebsite {
    constructor() {
        this.initializeComponents();
        this.setupEventListeners();
        this.setupDemos();
        this.setupAnimations();
    }

    initializeComponents() {
        // Initialize tooltips
        const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
        this.tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
            return new bootstrap.Tooltip(tooltipTriggerEl);
        });

        // Initialize popovers
        const popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'));
        this.popoverList = popoverTriggerList.map(function (popoverTriggerEl) {
            return new bootstrap.Popover(popoverTriggerEl);
        });
    }

    setupEventListeners() {
        // Smooth scrolling for anchor links
        document.querySelectorAll('a[href^="#"]').forEach(anchor => {
            anchor.addEventListener('click', (e) => {
                const targetId = anchor.getAttribute('href').slice(1);
                const targetElement = document.getElementById(targetId);
                
                if (targetElement) {
                    e.preventDefault();
                    targetElement.scrollIntoView({
                        behavior: 'smooth',
                        block: 'start'
                    });
                    
                    // Manage focus for accessibility
                    if (window.accessibilityManager) {
                        window.accessibilityManager.manageFocus(targetElement);
                    }
                }
            });
        });

        // Form submission handling
        this.setupFormHandling();
        
        // Progress bar animations
        this.setupProgressAnimations();
        
        // Card hover effects
        this.setupCardEffects();
    }

    setupFormHandling() {
        const forms = document.querySelectorAll('form');
        forms.forEach(form => {
            form.addEventListener('submit', (e) => {
                this.validateForm(form, e);
            });

            // Real-time validation
            const inputs = form.querySelectorAll('input, textarea, select');
            inputs.forEach(input => {
                input.addEventListener('blur', () => {
                    this.validateField(input);
                });
            });
        });

        // Newsletter form handling
        const newsletterForms = document.querySelectorAll('.newsletter-form');
        newsletterForms.forEach(form => {
            form.addEventListener('submit', (e) => {
                this.handleNewsletterSubmission(form, e);
            });
        });
    }

    validateForm(form, event) {
        let isValid = true;
        const requiredFields = form.querySelectorAll('[required]');
        
        requiredFields.forEach(field => {
            if (!this.validateField(field)) {
                isValid = false;
            }
        });

        if (!isValid) {
            event.preventDefault();
            
            // Focus first invalid field
            const firstInvalid = form.querySelector('.is-invalid');
            if (firstInvalid) {
                firstInvalid.focus();
                
                // Announce error to screen readers
                if (window.accessibilityManager) {
                    window.accessibilityManager.announceToScreenReader('Please correct the errors in the form');
                }
            }
        }
    }

    validateField(field) {
        const value = field.value.trim();
        let isValid = true;
        let errorMessage = '';

        // Check if required field is empty
        if (field.hasAttribute('required') && !value) {
            isValid = false;
            errorMessage = 'This field is required';
        }

        // Email validation
        if (field.type === 'email' && value) {
            const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
            if (!emailRegex.test(value)) {
                isValid = false;
                errorMessage = 'Please enter a valid email address';
            }
        }

        // Length validation
        const minLength = field.getAttribute('minlength');
        const maxLength = field.getAttribute('maxlength');
        
        if (minLength && value.length < parseInt(minLength)) {
            isValid = false;
            errorMessage = `Minimum ${minLength} characters required`;
        }
        
        if (maxLength && value.length > parseInt(maxLength)) {
            isValid = false;
            errorMessage = `Maximum ${maxLength} characters allowed`;
        }

        // Update field state
        if (isValid) {
            field.classList.remove('is-invalid');
            field.classList.add('is-valid');
            this.removeFieldError(field);
        } else {
            field.classList.remove('is-valid');
            field.classList.add('is-invalid');
            this.showFieldError(field, errorMessage);
        }

        return isValid;
    }

    showFieldError(field, message) {
        // Remove existing error
        this.removeFieldError(field);

        // Create error element
        const errorElement = document.createElement('div');
        errorElement.className = 'invalid-feedback';
        errorElement.textContent = message;
        errorElement.id = `${field.id || field.name}-error`;

        // Insert after field
        field.parentNode.insertBefore(errorElement, field.nextSibling);

        // Update ARIA attributes
        field.setAttribute('aria-invalid', 'true');
        field.setAttribute('aria-describedby', errorElement.id);
    }

    removeFieldError(field) {
        const existingError = field.parentNode.querySelector('.invalid-feedback');
        if (existingError) {
            existingError.remove();
        }
        
        field.removeAttribute('aria-invalid');
        field.removeAttribute('aria-describedby');
    }

    handleNewsletterSubmission(form, event) {
        const submitButton = form.querySelector('button[type="submit"]');
        const originalText = submitButton.innerHTML;
        
        // Show loading state
        submitButton.innerHTML = '<i class="fas fa-spinner fa-spin" aria-hidden="true"></i> Subscribing...';
        submitButton.disabled = true;

        // Reset button after submission (form will reload page)
        setTimeout(() => {
            submitButton.innerHTML = originalText;
            submitButton.disabled = false;
        }, 3000);
    }

    setupDemos() {
        this.setupTTSDemo();
        this.setupVoiceDemo();
        this.setupGestureDemo();
        this.setupContrastDemo();
    }

    setupTTSDemo() {
        const playButton = document.getElementById('play-tts');
        const stopButton = document.getElementById('stop-tts');
        const textArea = document.getElementById('tts-text');

        if (playButton && window.ttsManager) {
            playButton.addEventListener('click', () => {
                const text = textArea ? textArea.value : 'Hello from PrismaOS';
                
                playButton.disabled = true;
                playButton.innerHTML = '<i class="fas fa-spinner fa-spin" aria-hidden="true"></i> Speaking...';
                
                window.ttsManager.speak(text, {
                    onStart: () => {
                        if (stopButton) stopButton.disabled = false;
                    },
                    onEnd: () => {
                        playButton.disabled = false;
                        playButton.innerHTML = '<i class="fas fa-play" aria-hidden="true"></i> Play Text';
                        if (stopButton) stopButton.disabled = true;
                    },
                    onError: (error) => {
                        console.error('TTS Error:', error);
                        playButton.disabled = false;
                        playButton.innerHTML = '<i class="fas fa-play" aria-hidden="true"></i> Play Text';
                        if (stopButton) stopButton.disabled = true;
                        
                        // Show error message
                        this.showNotification('Error: Could not play text-to-speech', 'error');
                    }
                });
            });
        }

        if (stopButton && window.ttsManager) {
            stopButton.addEventListener('click', () => {
                window.ttsManager.stop();
                playButton.disabled = false;
                playButton.innerHTML = '<i class="fas fa-play" aria-hidden="true"></i> Play Text';
                stopButton.disabled = true;
            });
        }
    }

    setupVoiceDemo() {
        const startButton = document.getElementById('start-voice');
        const stopButton = document.getElementById('stop-voice');
        const voiceStatus = document.getElementById('voice-status');
        const voiceIndicator = document.getElementById('voice-indicator');
        const voiceState = document.getElementById('voice-state');
        const voiceCommand = document.getElementById('voice-command');

        if (!startButton || !('webkitSpeechRecognition' in window || 'SpeechRecognition' in window)) {
            if (startButton) {
                startButton.disabled = true;
                startButton.innerHTML = '<i class="fas fa-microphone-slash" aria-hidden="true"></i> Not Supported';
            }
            return;
        }

        const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
        let recognition = null;

        startButton.addEventListener('click', () => {
            recognition = new SpeechRecognition();
            recognition.continuous = true;
            recognition.interimResults = true;
            recognition.lang = 'en-US';

            recognition.onstart = () => {
                startButton.disabled = true;
                stopButton.disabled = false;
                voiceStatus.classList.add('listening');
                voiceIndicator.innerHTML = '<i class="fas fa-microphone text-success" aria-hidden="true"></i>';
                voiceState.textContent = 'Listening...';
                voiceCommand.textContent = 'Say something...';
                
                if (window.accessibilityManager) {
                    window.accessibilityManager.announceToScreenReader('Voice recognition started');
                }
            };

            recognition.onresult = (event) => {
                const results = Array.from(event.results);
                const transcript = results
                    .map(result => result[0].transcript)
                    .join('');

                voiceCommand.textContent = `You said: "${transcript}"`;
                
                // Handle specific commands
                this.handleVoiceCommand(transcript.toLowerCase());
            };

            recognition.onerror = (event) => {
                console.error('Speech recognition error:', event.error);
                this.stopVoiceRecognition();
                voiceCommand.textContent = `Error: ${event.error}`;
            };

            recognition.onend = () => {
                this.stopVoiceRecognition();
            };

            recognition.start();
        });

        stopButton.addEventListener('click', () => {
            if (recognition) {
                recognition.stop();
            }
            this.stopVoiceRecognition();
        });

        this.stopVoiceRecognition = () => {
            startButton.disabled = false;
            stopButton.disabled = true;
            voiceStatus.classList.remove('listening');
            voiceIndicator.innerHTML = '<i class="fas fa-microphone-slash text-muted" aria-hidden="true"></i>';
            voiceState.textContent = 'Not Active';
            
            if (window.accessibilityManager) {
                window.accessibilityManager.announceToScreenReader('Voice recognition stopped');
            }
        };
    }

    handleVoiceCommand(command) {
        const responses = {
            'hello': 'Hello! Welcome to PrismaOS.',
            'what time is it': `The current time is ${new Date().toLocaleTimeString()}.`,
            'help me navigate': 'Use Tab to navigate between elements, Enter to activate buttons, and Escape to close dialogs.',
            'open settings': 'Settings would open here in the full PrismaOS interface.',
            'read notifications': 'You have no new notifications.',
            'go home': 'Navigating to home screen...',
            'increase font size': 'Font size increased.',
            'high contrast': 'High contrast mode toggled.'
        };

        for (const [trigger, response] of Object.entries(responses)) {
            if (command.includes(trigger)) {
                if (window.ttsManager) {
                    window.ttsManager.speak(response);
                }
                
                // Execute relevant actions
                if (trigger === 'increase font size' && window.accessibilityManager) {
                    window.accessibilityManager.adjustFontSize('increase');
                } else if (trigger === 'high contrast' && window.accessibilityManager) {
                    window.accessibilityManager.toggleHighContrast();
                }
                
                break;
            }
        }
    }

    setupGestureDemo() {
        const gestureArea = document.getElementById('gesture-area');
        const gestureInstructions = gestureArea ? gestureArea.querySelector('.gesture-instructions') : null;
        const gestureFeedback = document.getElementById('gesture-feedback');
        const gestureType = document.getElementById('gesture-type');
        const gestureDescription = document.getElementById('gesture-description');

        if (!gestureArea) return;

        let touchStartTime = 0;
        let touchStartX = 0;
        let touchStartY = 0;
        let lastTap = 0;

        // Touch events
        gestureArea.addEventListener('touchstart', (e) => {
            e.preventDefault();
            touchStartTime = Date.now();
            touchStartX = e.touches[0].clientX;
            touchStartY = e.touches[0].clientY;
        });

        gestureArea.addEventListener('touchend', (e) => {
            e.preventDefault();
            const touchEndTime = Date.now();
            const touchEndX = e.changedTouches[0].clientX;
            const touchEndY = e.changedTouches[0].clientY;
            
            const timeDiff = touchEndTime - touchStartTime;
            const xDiff = touchEndX - touchStartX;
            const yDiff = touchEndY - touchStartY;
            
            this.handleGesture(xDiff, yDiff, timeDiff, touchEndTime - lastTap);
            lastTap = touchEndTime;
        });

        // Mouse events for desktop
        let mouseDown = false;
        let mouseStartX = 0;
        let mouseStartY = 0;
        let mouseStartTime = 0;

        gestureArea.addEventListener('mousedown', (e) => {
            mouseDown = true;
            mouseStartX = e.clientX;
            mouseStartY = e.clientY;
            mouseStartTime = Date.now();
        });

        gestureArea.addEventListener('mouseup', (e) => {
            if (!mouseDown) return;
            
            mouseDown = false;
            const timeDiff = Date.now() - mouseStartTime;
            const xDiff = e.clientX - mouseStartX;
            const yDiff = e.clientY - mouseStartY;
            
            this.handleGesture(xDiff, yDiff, timeDiff, 0);
        });

        // Keyboard events
        gestureArea.addEventListener('keydown', (e) => {
            let gestureType = '';
            let description = '';

            switch (e.key) {
                case 'Enter':
                case ' ':
                    gestureType = 'Activation';
                    description = 'Element activated';
                    break;
                case 'ArrowRight':
                    gestureType = 'Swipe Right';
                    description = 'Navigate to next item';
                    break;
                case 'ArrowLeft':
                    gestureType = 'Swipe Left';
                    description = 'Navigate to previous item';
                    break;
                default:
                    return;
            }

            this.showGestureFeedback(gestureType, description);
        });

        this.handleGesture = (xDiff, yDiff, timeDiff, tapInterval) => {
            const minSwipeDistance = 50;
            const maxTapTime = 300;
            const doubleTapThreshold = 300;

            let gestureType = '';
            let description = '';

            if (Math.abs(xDiff) > minSwipeDistance || Math.abs(yDiff) > minSwipeDistance) {
                // Swipe gesture
                if (Math.abs(xDiff) > Math.abs(yDiff)) {
                    if (xDiff > 0) {
                        gestureType = 'Swipe Right';
                        description = 'Navigate to next item';
                    } else {
                        gestureType = 'Swipe Left';
                        description = 'Navigate to previous item';
                    }
                } else {
                    if (yDiff > 0) {
                        gestureType = 'Swipe Down';
                        description = 'Scroll down or expand';
                    } else {
                        gestureType = 'Swipe Up';
                        description = 'Scroll up or collapse';
                    }
                }
            } else if (timeDiff < maxTapTime) {
                // Tap gesture
                if (tapInterval < doubleTapThreshold) {
                    gestureType = 'Double Tap';
                    description = 'Activate or open item';
                } else {
                    gestureType = 'Single Tap';
                    description = 'Select item';
                }
            }

            if (gestureType) {
                this.showGestureFeedback(gestureType, description);
            }
        };

        this.showGestureFeedback = (type, description) => {
            if (gestureInstructions) gestureInstructions.classList.add('d-none');
            if (gestureFeedback) gestureFeedback.classList.remove('d-none');
            if (gestureType) gestureType.textContent = type;
            if (gestureDescription) gestureDescription.textContent = description;

            // Announce to screen readers
            if (window.accessibilityManager) {
                window.accessibilityManager.announceToScreenReader(`${type}: ${description}`);
            }

            // Hide feedback after 3 seconds
            setTimeout(() => {
                if (gestureInstructions) gestureInstructions.classList.remove('d-none');
                if (gestureFeedback) gestureFeedback.classList.add('d-none');
            }, 3000);
        };
    }

    setupContrastDemo() {
        const toggleButton = document.getElementById('toggle-contrast-demo');
        const preview = document.getElementById('contrast-preview');

        if (toggleButton && preview) {
            toggleButton.addEventListener('click', () => {
                preview.classList.toggle('high-contrast');
                
                const isHighContrast = preview.classList.contains('high-contrast');
                toggleButton.textContent = isHighContrast ? 
                    'Disable High Contrast' : 'Enable High Contrast';
                
                if (window.accessibilityManager) {
                    const message = isHighContrast ? 
                        'High contrast preview enabled' : 'High contrast preview disabled';
                    window.accessibilityManager.announceToScreenReader(message);
                }
            });
        }
    }

    setupProgressAnimations() {
        const progressBars = document.querySelectorAll('.progress-bar');
        
        const animateProgress = (entries, observer) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    const progressBar = entry.target;
                    const targetWidth = progressBar.getAttribute('aria-valuenow') + '%';
                    progressBar.style.width = targetWidth;
                    observer.unobserve(progressBar);
                }
            });
        };

        if ('IntersectionObserver' in window) {
            const observer = new IntersectionObserver(animateProgress, {
                threshold: 0.5
            });

            progressBars.forEach(bar => {
                bar.style.width = '0%';
                observer.observe(bar);
            });
        }
    }

    setupCardEffects() {
        const cards = document.querySelectorAll('.feature-card, .tech-card, .program-card, .event-card');
        
        cards.forEach(card => {
            card.addEventListener('mouseenter', () => {
                if (!document.body.classList.contains('reduce-motion')) {
                    card.style.transform = 'translateY(-5px)';
                }
            });
            
            card.addEventListener('mouseleave', () => {
                card.style.transform = 'translateY(0)';
            });
        });
    }

    setupAnimations() {
        // Fade in animations for elements as they come into view
        const animatedElements = document.querySelectorAll('.feature-card, .timeline-item, .stat-card');
        
        const fadeInObserver = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    entry.target.style.opacity = '1';
                    entry.target.style.transform = 'translateY(0)';
                }
            });
        }, { threshold: 0.1 });

        animatedElements.forEach(element => {
            element.style.opacity = '0';
            element.style.transform = 'translateY(20px)';
            element.style.transition = 'opacity 0.6s ease, transform 0.6s ease';
            
            fadeInObserver.observe(element);
        });
    }

    showNotification(message, type = 'info') {
        const notification = document.createElement('div');
        notification.className = `alert alert-${type} alert-dismissible fade show`;
        notification.style.position = 'fixed';
        notification.style.top = '100px';
        notification.style.right = '20px';
        notification.style.zIndex = '9999';
        notification.style.minWidth = '300px';
        
        notification.innerHTML = `
            ${message}
            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
        `;
        
        document.body.appendChild(notification);
        
        // Auto-remove after 5 seconds
        setTimeout(() => {
            if (notification.parentNode) {
                notification.remove();
            }
        }, 5000);
        
        // Announce to screen readers
        if (window.accessibilityManager) {
            window.accessibilityManager.announceToScreenReader(message);
        }
    }

    // Utility method to handle loading states
    setLoadingState(element, isLoading) {
        if (isLoading) {
            element.classList.add('loading');
            element.setAttribute('aria-busy', 'true');
        } else {
            element.classList.remove('loading');
            element.removeAttribute('aria-busy');
        }
    }

    // Method to update live regions for dynamic content
    updateLiveRegion(message, priority = 'polite') {
        const liveRegion = document.getElementById('live-region') || 
                          document.getElementById('accessibility-announcements');
        
        if (liveRegion) {
            liveRegion.setAttribute('aria-live', priority);
            liveRegion.textContent = message;
            
            // Clear after announcement
            setTimeout(() => {
                liveRegion.textContent = '';
            }, 1000);
        }
    }
}

// Initialize website functionality when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
    window.prismaOSWebsite = new PrismaOSWebsite();
    
    // Handle page visibility changes
    document.addEventListener('visibilitychange', () => {
        if (document.hidden) {
            // Stop any speech synthesis when page is hidden
            if (window.ttsManager && window.ttsManager.isSpeaking()) {
                window.ttsManager.pause();
            }
        } else {
            // Resume speech synthesis when page becomes visible
            if (window.ttsManager) {
                window.ttsManager.resume();
            }
        }
    });
    
    // Handle window resize for responsive adjustments
    let resizeTimeout;
    window.addEventListener('resize', () => {
        clearTimeout(resizeTimeout);
        resizeTimeout = setTimeout(() => {
            // Recalculate any size-dependent features
            const event = new CustomEvent('windowResized');
            document.dispatchEvent(event);
        }, 250);
    });
    
    // Add custom event listeners for accessibility features
    document.addEventListener('accessibilitySettingChanged', (event) => {
        console.log('Accessibility setting changed:', event.detail);
    });
});

// Handle service worker registration for PWA features (if needed in the future)
if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {
        // Service worker registration would go here if implementing PWA features
    });
}

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