(function($) {
    "use strict";

    var WidgetScrollMarqueeHandler = function($scope, $) {
        var $marqueeContainer = $scope.find('.crt-marquee-container');
        if (!$marqueeContainer.length) {
            return;
        }

        var $track = $marqueeContainer.find('.crt-marquee-track');
        var speed = parseFloat($marqueeContainer.data('speed')) || 50; 
        var direction = $marqueeContainer.data('direction') || 'left';
        var pauseOnHover = $marqueeContainer.data('pause-on-hover') === true;
        var scrollEffect = $marqueeContainer.data('scroll-effect') === true;

        if (typeof gsap === 'undefined') {
            return;
        }

        // To create a seamless infinite scroll, we need enough cloned items to cover the screen
        // But since we use JS to animate, it's easier to duplicate the content once
        // and tween the translation.
        
        // Clone the items and append them to the track
        var html = $track.html();
        
        var isVertical = (direction === 'up' || direction === 'down');
        
        // Ensure track is fully populated to scroll seamlessly
        // In some cases we might need more clones if the items are few.
        var repeatCount = 1;
        
        // If track size is smaller than container size, clone multiple times until it fills
        var trackSize = isVertical ? $track.outerHeight() : $track.outerWidth();
        var containerSize = isVertical ? $marqueeContainer.outerHeight() : $marqueeContainer.outerWidth();
        
        if (trackSize > 0 && trackSize < containerSize * 2) {
            repeatCount = Math.ceil((containerSize * 2) / trackSize);
        }
        
        for (var i = 0; i < repeatCount; i++) {
            $track.append(html);
        }

        // We re-measure the original group size to know how far to animate
        // But since CSS gap is applied, we must measure the full track and divide
        var totalSize = isVertical ? $track[0].scrollHeight : $track[0].scrollWidth;
        // The size of one original set of items including gaps
        var singleSetSize = totalSize / (repeatCount + 1);

        var duration = singleSetSize / speed;

        // Set up the animation
        var distance = singleSetSize;
        if (direction === 'left' || direction === 'up') distance = -distance;

        // If moving right or down, we start offset negatively and animate to 0
        if (direction === 'right' || direction === 'down') {
            if (isVertical) gsap.set($track, { y: -singleSetSize });
            else gsap.set($track, { x: -singleSetSize });
            distance = 0;
        }

        var animProps = {
            ease: "none",
            duration: duration,
            repeat: -1,
            // If direction is right or down, we reset to negative offset on restart
            onRepeat: function() {
                if(direction === 'right') gsap.set($track, { x: -singleSetSize });
                if(direction === 'down')  gsap.set($track, { y: -singleSetSize });
            }
        };

        if (isVertical) animProps.y = distance;
        else animProps.x = distance;

        var tween = gsap.to($track, animProps);

        if (pauseOnHover) {
            $marqueeContainer.on('mouseenter', function() {
                tween.pause();
            }).on('mouseleave', function() {
                tween.play();
            });
        }

        if (scrollEffect && typeof ScrollTrigger !== 'undefined') {
            var scrollTimeout;
            ScrollTrigger.create({
                start: 0,
                end: "max",
                onUpdate: function(self) {
                    var velocity = Math.abs(self.getVelocity() || 0);
                    // Add velocity to scale (e.g., speed up when scrolling fast)
                    var scale = 1 + velocity / 500; 
                    scale = Math.min(scale, 5); // cap speed

                    // self.direction is 1 (down) or -1 (up)
                    var dir = self.direction; 
                    
                    gsap.to(tween, {
                        timeScale: dir * scale,
                        duration: 0.2,
                        overwrite: true
                    });
                    
                    clearTimeout(scrollTimeout);
                    scrollTimeout = setTimeout(function() {
                        gsap.to(tween, {
                            timeScale: dir, // maintain direction after scrolling stops
                            duration: 0.5,
                            overwrite: true
                        });
                    }, 150);
                }
            });
        }
    };

    $(window).on('elementor/frontend/init', function() {
        elementorFrontend.hooks.addAction('frontend/element_ready/crt-scroll-marquee.default', WidgetScrollMarqueeHandler);
    });

})(jQuery);
