( function () {
    'use strict';

    function initAll( root ) {
        root = root || document;
        initKeyboard( root );
        initLineFill( root );
        initReveal( root );
    }

    /* ──────────────────────────────────────────────────
     * 1. Keyboard navigation for horizontal / carousel
     * ────────────────────────────────────────────────── */
    function initKeyboard( root ) {
        root.querySelectorAll(
            '.sitsel-tl-horizontal .sitsel-tl-items, .sitsel-tl-line-top-carousel .sitsel-tl-items'
        ).forEach( function ( el ) {
            if ( el.dataset.kbInit ) return; // prevent double-binding
            el.dataset.kbInit = '1';
            el.setAttribute( 'tabindex', '0' );
            el.addEventListener( 'keydown', function ( e ) {
                if ( e.key === 'ArrowRight' )     { this.scrollLeft += 200; e.preventDefault(); }
                else if ( e.key === 'ArrowLeft' ) { this.scrollLeft -= 200; e.preventDefault(); }
            } );
        } );
    }

    /* ──────────────────────────────────────────────────
     * 2. Line fill + dot active state on scroll
     * ────────────────────────────────────────────────── */
    function initLineFill( root ) {
        root.querySelectorAll( '.sitsel-tl-wrapper.has-line' ).forEach( function ( wrapper ) {
            if ( wrapper.dataset.lineFillInit ) return; // prevent double-binding
            wrapper.dataset.lineFillInit = '1';

            var items = Array.from( wrapper.querySelectorAll( '.sitsel-tl-item' ) );
            if ( ! items.length ) return;

            var isCarousel = wrapper.classList.contains( 'sitsel-tl-horizontal' ) ||
                             wrapper.classList.contains( 'sitsel-tl-line-top-carousel' );

            var scrollContainer = isCarousel
                ? wrapper.querySelector( '.sitsel-tl-items' )
                : null;

            function setCarouselLineWidth() {
                if ( ! isCarousel || ! scrollContainer ) return;
                wrapper.style.setProperty( '--tl-carousel-line-width', scrollContainer.scrollWidth + 'px' );
            }

            function update() {
                if ( isCarousel && scrollContainer ) {
                    var maxScroll = scrollContainer.scrollWidth - scrollContainer.clientWidth;
                    var fill      = maxScroll > 0
                        ? Math.min( 100, ( scrollContainer.scrollLeft / maxScroll ) * 100 )
                        : 0;
                    var containerRect = scrollContainer.getBoundingClientRect();
                    var visibleMidX   = containerRect.left + scrollContainer.clientWidth / 2;
                    items.forEach( function ( item ) {
                        var dot      = item.querySelector( '.sitsel-tline-dot' );
                        var itemRect = item.getBoundingClientRect();
                        var itemMidX = itemRect.left + itemRect.width / 2;
                        if ( dot ) dot.classList.toggle( 'sitsel-tline-dot--active', itemMidX <= visibleMidX );
                    } );
                    wrapper.style.setProperty( '--tl-line-fill', fill.toFixed( 2 ) + '%' );
                    return;
                }

                var viewportMid     = window.innerHeight / 2;
                var lastPassedIndex = -1;
                items.forEach( function ( item, idx ) {
                    if ( item.getBoundingClientRect().top < viewportMid ) {
                        lastPassedIndex = idx;
                    }
                } );

                var fill = 0;
                if ( lastPassedIndex >= 0 ) {
                    var line = wrapper.querySelector( '.sitsel-tl-line' );
                    if ( line ) {
                        var lineRect = line.getBoundingClientRect();
                        if ( lastPassedIndex >= items.length - 1 ) {
                            fill = 100;
                        } else {
                            var curr     = items[ lastPassedIndex ];
                            var next     = items[ lastPassedIndex + 1 ];
                            var currRect = curr.getBoundingClientRect();
                            var nextRect = next.getBoundingClientRect();
                            var currTop  = currRect.top - lineRect.top;
                            var nextTop  = nextRect.top - lineRect.top;
                            var span     = nextTop - currTop || 1;
                            var vpFront  = viewportMid - lineRect.top;
                            var t        = Math.max( 0, Math.min( 1, ( vpFront - currTop ) / span ) );
                            var speedFactor = parseFloat( wrapper.dataset.fillSpeed ) || 1.0;
                            if ( speedFactor !== 1.0 ) { t = Math.min( 1, t * speedFactor ); }
                            var pos = currTop + t * ( nextTop - currTop );
                            if ( lineRect.height > 0 ) {
                                fill = Math.min( 100, ( pos / lineRect.height ) * 100 );
                            }
                        }

                        var fillPixels = ( fill / 100 ) * lineRect.height;
                        items.forEach( function ( item ) {
                            var dot = item.querySelector( '.sitsel-tline-dot' );
                            if ( ! dot ) return;
                            var iconTop  = dot.getBoundingClientRect().top - lineRect.top;
                            var isActive = iconTop < fillPixels;
                            dot.classList.toggle( 'sitsel-tline-dot--active', isActive );
                            dot.classList.toggle( 'sitsel-change-border-color', isActive );
                        } );
                    }
                }
                wrapper.style.setProperty( '--tl-line-fill', fill.toFixed( 2 ) + '%' );
            }

            var rafPending = false;
            function onScroll() {
                if ( rafPending ) return;
                rafPending = true;
                requestAnimationFrame( function () { rafPending = false; update(); } );
            }

            var resizeTimer;
            function onResize() {
                clearTimeout( resizeTimer );
                resizeTimer = setTimeout( function () { setCarouselLineWidth(); update(); }, 100 );
            }

            if ( isCarousel && scrollContainer ) {
                scrollContainer.addEventListener( 'scroll', onScroll, { passive: true } );
            } else {
                window.addEventListener( 'scroll', onScroll, { passive: true } );
            }
            window.addEventListener( 'resize', onResize, { passive: true } );

            setCarouselLineWidth();
            update();
        } );
    }

   
    function initReveal( root ) {
        root.querySelectorAll( '.sitsel-tl-wrapper' ).forEach( function ( wrapper ) {
            if ( wrapper.dataset.revealInit ) return; // prevent double-binding
            wrapper.dataset.revealInit = '1';

            var anim   = wrapper.dataset.animation || 'none';
            var dur    = ( parseInt( wrapper.dataset.duration, 10 ) || 600 ) / 1000;
            var offset = parseInt( wrapper.dataset.offset, 10 ) || 150;

            if ( 'none' === anim ) return;

            var itemEls = Array.from( wrapper.querySelectorAll( '.sitsel-tl-item' ) );
            if ( ! itemEls.length ) return;

            var animClass = 'sitsel-tl-anim-' + anim;

            /* ── STEP 1: Hide ALL items synchronously before any paint ── */
            itemEls.forEach( function ( el ) {
                el.style.setProperty( '--anim-dur', dur + 's' );
                el.classList.add( animClass );
            } );

            /* ── STEP 2: Reveal helper ── */
            function reveal( el, delay ) {
                delay = delay || 0;
                setTimeout( function () {
                    requestAnimationFrame( function () {
                        el.classList.add( 'sitsel-tl-visible' );
                    } );
                }, delay );
            }

            if ( window.IntersectionObserver ) {
                var observer = new IntersectionObserver( function ( entries ) {
                    entries.forEach( function ( entry ) {
                        if ( entry.isIntersecting ) {
                            reveal( entry.target, 0 );
                            observer.unobserve( entry.target );
                        }
                    } );
                }, {
                    /* negative bottom margin delays trigger until item is
                       `offset` px above the bottom of the viewport */
                    rootMargin : '0px 0px -' + offset + 'px 0px',
                    threshold  : 0
                } );

               
                var staggerDelay = 0;
                itemEls.forEach( function ( el, i ) {
                    var inView = el.getBoundingClientRect().top < window.innerHeight - offset;
                    if ( inView ) {
                        /* Don't observe – animate directly with stagger */
                        reveal( el, staggerDelay );
                        staggerDelay += 80;
                    } else {
                        observer.observe( el );
                    }
                } );

            } else {
                /* ── Fallback: manual scroll check ── */
                var revealed = new WeakSet();
                var staggerDelay = 0;

                function checkVisibility() {
                    var threshold = window.innerHeight - offset;
                    itemEls.forEach( function ( el ) {
                        if ( revealed.has( el ) ) return;
                        if ( el.getBoundingClientRect().top < threshold ) {
                            revealed.add( el );
                            reveal( el, 0 );
                        }
                    } );
                }

                /* Animate in-viewport items on load with stagger */
                itemEls.forEach( function ( el ) {
                    if ( el.getBoundingClientRect().top < window.innerHeight - offset ) {
                        revealed.add( el );
                        reveal( el, staggerDelay );
                        staggerDelay += 80;
                    }
                } );

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

    /* ──────────────────────────────────────────────────
     * Boot
     * ────────────────────────────────────────────────── */
    function boot() {
        initAll( document );
    }

    /* Standard DOM ready */
    if ( document.readyState === 'loading' ) {
        document.addEventListener( 'DOMContentLoaded', boot );
    } else {
        boot(); // already parsed
    }

    window.addEventListener( 'elementor/frontend/init', function () {
        if ( ! window.elementorFrontend ) return;

        elementorFrontend.hooks.addAction(
            'frontend/element_ready/sitsel_post_timeline.default',
            function ( $scope ) {
                /* $scope is a jQuery object wrapping the widget root */
                var el = $scope && $scope[0] ? $scope[0] : document;
                // Remove init flags so the widget re-initialises cleanly
                el.querySelectorAll( '.sitsel-tl-wrapper' ).forEach( function ( w ) {
                    delete w.dataset.revealInit;
                    delete w.dataset.lineFillInit;
                } );
                el.querySelectorAll( '.sitsel-tl-items' ).forEach( function ( i ) {
                    delete i.dataset.kbInit;
                } );
                initAll( el );
            }
        );
    } );

} )();