/* ============================================
   RSL Hero Component
   Version: 1.0.0
   Description: Premium hero sections with parallax, typewriter effects,
   and scroll indicators. Fully ADA compliant.
   ============================================ */

(function() {
    'use strict';

    // Initialize RSL namespace
    window.RSL = window.RSL || {};

    /**
     * Hero Component
     * Provides premium hero sections with accessibility-first design
     */
    window.RSL.Hero = {

        // Track initialized heroes
        instances: new Set(),

        // Default configuration
        defaults: {
            parallaxSpeed: 0.5,
            typewriterSpeed: 50,
            typewriterDelay: 1000,
            scrollTarget: null
        },

        /**
         * Initialize all hero components on the page
         */
        init: function() {
            var heroes = document.querySelectorAll('.rsl-hero');
            var self = this;

            heroes.forEach(function(hero) {
                if (!self.instances.has(hero)) {
                    self.create(hero);
                    self.instances.add(hero);
                }
            });

            return this;
        },

        /**
         * Create a single hero instance
         * @param {HTMLElement} hero - The hero element
         * @param {Object} options - Configuration options
         */
        create: function(hero, options) {
            if (!hero) return null;

            var config = this._mergeConfig(hero, options);

            // Set up ARIA attributes
            this._setupAccessibility(hero);

            // Set up skip link
            this._setupSkipLink(hero);

            // Set up parallax effect
            if (hero.hasAttribute('data-hero-parallax')) {
                this._setupParallax(hero, config);
            }

            // Set up typewriter effect
            var typewriterEl = hero.querySelector('[data-hero-typewriter]');
            if (typewriterEl) {
                this._setupTypewriter(typewriterEl, config);
            }

            // Set up scroll indicator
            var scrollIndicator = hero.querySelector('.rsl-hero-scroll');
            if (scrollIndicator) {
                this._setupScrollIndicator(hero, scrollIndicator, config);
            }

            // Set up video background
            var video = hero.querySelector('.rsl-hero-background video');
            if (video) {
                this._setupVideoBackground(video);
            }

            // Mark as initialized
            hero.setAttribute('data-hero-initialized', 'true');

            return hero;
        },

        /**
         * Merge configuration from data attributes and options
         * @private
         */
        _mergeConfig: function(hero, options) {
            var config = Object.assign({}, this.defaults, options || {});

            // Read data attributes
            if (hero.hasAttribute('data-hero-parallax-speed')) {
                config.parallaxSpeed = parseFloat(hero.getAttribute('data-hero-parallax-speed'));
            }

            if (hero.hasAttribute('data-hero-typewriter-speed')) {
                config.typewriterSpeed = parseInt(hero.getAttribute('data-hero-typewriter-speed'), 10);
            }

            if (hero.hasAttribute('data-hero-scroll-target')) {
                config.scrollTarget = hero.getAttribute('data-hero-scroll-target');
            }

            return config;
        },

        /**
         * Set up accessibility attributes
         * @private
         */
        _setupAccessibility: function(hero) {
            // Ensure hero has proper role
            if (!hero.hasAttribute('role')) {
                hero.setAttribute('role', 'region');
            }

            // Set up aria-labelledby if heading exists
            var heading = hero.querySelector('.rsl-hero-heading');
            if (heading) {
                if (!heading.id) {
                    heading.id = 'rsl-hero-heading-' + Date.now();
                }
                hero.setAttribute('aria-labelledby', heading.id);
            }

            // Ensure background images are properly marked
            var bgImage = hero.querySelector('.rsl-hero-background img');
            if (bgImage) {
                if (!bgImage.hasAttribute('alt')) {
                    bgImage.setAttribute('alt', '');
                }
                bgImage.setAttribute('aria-hidden', 'true');
            }

            // Mark decorative overlay
            var overlay = hero.querySelector('.rsl-hero-overlay');
            if (overlay) {
                overlay.setAttribute('aria-hidden', 'true');
            }
        },

        /**
         * Set up skip link for keyboard navigation
         * @private
         */
        _setupSkipLink: function(hero) {
            // Check if skip link already exists
            if (hero.querySelector('.rsl-hero-skip')) return;

            // Find next section to skip to
            var nextSection = hero.nextElementSibling;
            if (!nextSection) return;

            // Ensure next section has an ID
            if (!nextSection.id) {
                nextSection.id = 'rsl-hero-next-' + Date.now();
            }

            // Create skip link
            var skipLink = document.createElement('a');
            skipLink.className = 'rsl-hero-skip';
            skipLink.href = '#' + nextSection.id;
            skipLink.textContent = 'Skip to main content';

            // Insert at beginning of hero
            hero.insertBefore(skipLink, hero.firstChild);

            // Handle click
            skipLink.addEventListener('click', function(e) {
                e.preventDefault();
                nextSection.focus();
                nextSection.scrollIntoView({ behavior: 'smooth', block: 'start' });
            });
        },

        /**
         * Set up parallax scrolling effect
         * @private
         */
        _setupParallax: function(hero, config) {
            // Check for reduced motion preference
            if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
                return;
            }

            var background = hero.querySelector('.rsl-hero-background');
            if (!background) return;

            var speed = config.parallaxSpeed;
            var ticking = false;

            function updateParallax() {
                var scrolled = window.pageYOffset;
                var heroRect = hero.getBoundingClientRect();
                var heroTop = heroRect.top + scrolled;
                var heroHeight = hero.offsetHeight;

                // Only apply parallax when hero is in view
                if (scrolled < heroTop + heroHeight && scrolled + window.innerHeight > heroTop) {
                    var offset = (scrolled - heroTop) * speed;
                    // Clamp offset to never be negative (prevents gap at top)
                    offset = Math.max(0, offset);
                    background.style.transform = 'translateY(' + offset + 'px)';
                }

                ticking = false;
            }

            function onScroll() {
                if (!ticking) {
                    requestAnimationFrame(updateParallax);
                    ticking = true;
                }
            }

            window.addEventListener('scroll', onScroll, { passive: true });

            // Initial call to set correct position
            updateParallax();

            // Store cleanup function
            hero._cleanupParallax = function() {
                window.removeEventListener('scroll', onScroll);
            };
        },

        /**
         * Set up typewriter effect
         * @private
         */
        _setupTypewriter: function(element, config) {
            // Check for reduced motion preference - show text immediately
            if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
                return;
            }

            // Prevent double-initialization - check if already set up
            if (element.hasAttribute('data-typewriter-initialized')) {
                return;
            }

            // Store original text before any manipulation
            var text = element.getAttribute('data-typewriter-text') || element.textContent;

            // Guard against empty text
            if (!text || text.trim() === '') {
                return;
            }

            // Store the original text for potential re-initialization
            element.setAttribute('data-typewriter-text', text);
            element.setAttribute('data-typewriter-initialized', 'true');

            var speed = config.typewriterSpeed;
            var delay = config.typewriterDelay;

            // Clear the element
            element.textContent = '';
            element.setAttribute('aria-label', text);

            // Create cursor
            var cursor = document.createElement('span');
            cursor.className = 'rsl-hero-typewriter-cursor';
            cursor.setAttribute('aria-hidden', 'true');

            // Create text container
            var textContainer = document.createElement('span');
            textContainer.className = 'rsl-hero-typewriter-text';
            textContainer.setAttribute('aria-hidden', 'true');

            element.appendChild(textContainer);
            element.appendChild(cursor);

            var typingStarted = false;

            function startTyping() {
                if (typingStarted) return;
                typingStarted = true;
                setTimeout(function() {
                    typeText(textContainer, text, 0, speed, function() {
                        // Remove cursor after typing complete
                        setTimeout(function() {
                            cursor.style.display = 'none';
                        }, 2000);
                    });
                }, delay);
            }

            // Use IntersectionObserver to start typing when visible
            var observer = new IntersectionObserver(function(entries) {
                entries.forEach(function(entry) {
                    if (entry.isIntersecting) {
                        observer.disconnect();
                        startTyping();
                    }
                });
            }, { threshold: 0.1 }); // Lowered threshold for better detection

            observer.observe(element);

            // Fallback: if not triggered within 2 seconds, start anyway
            // This handles cases like page builders where visibility detection may fail
            setTimeout(function() {
                if (!typingStarted) {
                    observer.disconnect();
                    startTyping();
                }
            }, 2000);

            function typeText(container, text, index, speed, callback) {
                if (index < text.length) {
                    container.textContent += text.charAt(index);
                    setTimeout(function() {
                        typeText(container, text, index + 1, speed, callback);
                    }, speed);
                } else if (callback) {
                    callback();
                }
            }
        },

        /**
         * Set up scroll indicator
         * @private
         */
        _setupScrollIndicator: function(hero, indicator, config) {
            var target = config.scrollTarget;
            var targetElement = null;

            if (target) {
                targetElement = document.querySelector(target);
            } else {
                // Default to next sibling
                targetElement = hero.nextElementSibling;
            }

            if (!targetElement) {
                indicator.style.display = 'none';
                return;
            }

            // Ensure target has ID for accessibility
            if (!targetElement.id) {
                targetElement.id = 'rsl-hero-scroll-target-' + Date.now();
            }

            // Handle click/keyboard
            function scrollToTarget(e) {
                e.preventDefault();
                targetElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
                targetElement.focus();
            }

            indicator.addEventListener('click', scrollToTarget);
            indicator.addEventListener('keydown', function(e) {
                if (e.key === 'Enter' || e.key === ' ') {
                    e.preventDefault();
                    scrollToTarget(e);
                }
            });

            // Set up proper ARIA
            indicator.setAttribute('role', 'button');
            indicator.setAttribute('tabindex', '0');
            indicator.setAttribute('aria-label', 'Scroll to next section');

            // Hide on scroll
            var hidden = false;
            window.addEventListener('scroll', function() {
                if (window.pageYOffset > 100 && !hidden) {
                    indicator.style.opacity = '0';
                    indicator.style.pointerEvents = 'none';
                    hidden = true;
                } else if (window.pageYOffset <= 100 && hidden) {
                    indicator.style.opacity = '';
                    indicator.style.pointerEvents = '';
                    hidden = false;
                }
            }, { passive: true });
        },

        /**
         * Set up video background with accessibility
         * @private
         */
        _setupVideoBackground: function(video) {
            // Check for reduced motion preference
            if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
                video.pause();
                video.currentTime = 0;
                return;
            }

            // Ensure video is muted and loops
            video.muted = true;
            video.loop = true;
            video.playsInline = true;
            video.setAttribute('aria-hidden', 'true');

            // Pause when not visible
            var observer = new IntersectionObserver(function(entries) {
                entries.forEach(function(entry) {
                    if (entry.isIntersecting) {
                        video.play().catch(function() {
                            // Autoplay failed, that's ok
                        });
                    } else {
                        video.pause();
                    }
                });
            }, { threshold: 0.25 });

            observer.observe(video);

            // Listen for reduced motion changes
            window.matchMedia('(prefers-reduced-motion: reduce)').addEventListener('change', function(e) {
                if (e.matches) {
                    video.pause();
                } else {
                    video.play().catch(function() {});
                }
            });
        },

        /**
         * Destroy a hero instance
         * @param {HTMLElement} hero - The hero element
         */
        destroy: function(hero) {
            if (!hero) return;

            // Clean up parallax
            if (hero._cleanupParallax) {
                hero._cleanupParallax();
            }

            // Remove skip link
            var skipLink = hero.querySelector('.rsl-hero-skip');
            if (skipLink) {
                skipLink.remove();
            }

            // Remove initialized attribute
            hero.removeAttribute('data-hero-initialized');

            // Remove from instances
            this.instances.delete(hero);
        },

        /**
         * Refresh all hero instances
         */
        refresh: function() {
            var self = this;
            this.instances.forEach(function(hero) {
                self.destroy(hero);
            });
            this.init();
        },

        /**
         * Programmatically scroll to hero's target
         * @param {HTMLElement} hero - The hero element
         */
        scrollToNext: function(hero) {
            var target = hero.getAttribute('data-hero-scroll-target');
            var targetElement = target ? document.querySelector(target) : hero.nextElementSibling;

            if (targetElement) {
                targetElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
                targetElement.focus();
            }
        }
    };

    // Auto-initialize on DOMContentLoaded
    document.addEventListener('DOMContentLoaded', function() {
        window.RSL.Hero.init();
    });

    // Re-initialize on dynamic content
    if (typeof MutationObserver !== 'undefined') {
        var observer = new MutationObserver(function(mutations) {
            mutations.forEach(function(mutation) {
                mutation.addedNodes.forEach(function(node) {
                    if (node.nodeType === 1) {
                        if (node.classList && node.classList.contains('rsl-hero')) {
                            window.RSL.Hero.create(node);
                            window.RSL.Hero.instances.add(node);
                        }
                        // Check children
                        var heroes = node.querySelectorAll && node.querySelectorAll('.rsl-hero:not([data-hero-initialized])');
                        if (heroes) {
                            heroes.forEach(function(hero) {
                                window.RSL.Hero.create(hero);
                                window.RSL.Hero.instances.add(hero);
                            });
                        }
                    }
                });
            });
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

})();
