(function ($) {
    "use strict";

    const initMediaScrubbing = ($scope) => {
        const container = $scope.find('.sifency-scrub-container')[0];
        if (!container) return;

        if (typeof gsap === 'undefined' || typeof ScrollTrigger === 'undefined') {
            console.error('Sifency: GSAP/ScrollTrigger missing.');
            return;
        }

        const pinWrapper = container.querySelector('.sifency-scrub-pin-wrapper');
        const durationSetting = container.dataset.duration || 300; // e.g., 300vh
        const scrollLength = `+=${durationSetting}%`;
        const fitType = container.dataset.fit || 'cover';
        const type = container.dataset.type;

        // ---------------------------------------------------------
        // LOGIC 1: IMAGE SEQUENCE (CANVAS)
        // ---------------------------------------------------------
        if (type === 'sequence') {
            const canvas = container.querySelector('.sifency-scrub-canvas');
            if (!canvas) return;

            const context = canvas.getContext('2d');
            const imageUrls = JSON.parse(canvas.dataset.images || '[]');
            
            if (imageUrls.length === 0) return;

            // Set canvas resolution strictly to screen size for sharpness
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;

            const frameCount = imageUrls.length;
            const images = [];
            const sequenceObj = { frame: 0 }; // Object to animate via GSAP

            // Render function to draw image centered/covered
            const renderCanvas = () => {
                if (!images[sequenceObj.frame]) return; // If not loaded yet
                const img = images[sequenceObj.frame];
                
                context.clearRect(0, 0, canvas.width, canvas.height);

                let hRatio = canvas.width / img.width;
                let vRatio = canvas.height / img.height;
                let ratio  = fitType === 'cover' ? Math.max(hRatio, vRatio) : Math.min(hRatio, vRatio);

                let centerShift_x = (canvas.width - img.width * ratio) / 2;
                let centerShift_y = (canvas.height - img.height * ratio) / 2;

                context.drawImage(img, 0, 0, img.width, img.height, centerShift_x, centerShift_y, img.width * ratio, img.height * ratio);
            };

            // Preload the first image immediately to show something
            const firstImg = new Image();
            firstImg.src = imageUrls[0];
            firstImg.onload = () => {
                images[0] = firstImg;
                renderCanvas(); // Draw first frame
            };

            // Preload the rest asynchronously
            for (let i = 1; i < frameCount; i++) {
                const img = new Image();
                img.src = imageUrls[i];
                images.push(img);
            }

            // Update canvas size on window resize
            window.addEventListener('resize', () => {
                canvas.width = window.innerWidth;
                canvas.height = window.innerHeight;
                renderCanvas();
            });

            // The Magic ScrollTrigger Timeline
            gsap.to(sequenceObj, {
                frame: frameCount - 1, // Animate from frame 0 to last frame
                snap: "frame",         // Snap to whole numbers
                ease: "none",          // Linear progress
                scrollTrigger: {
                    trigger: container,
                    start: "top top",
                    end: scrollLength, // e.g. 300% of viewport height
                    scrub: 0.5,        // Small smoothing factor (Works flawless with Lenis)
                    pin: true,         // Pin the section while scrolling
                },
                onUpdate: renderCanvas // Re-draw canvas on every scroll tick
            });
        }

        // ---------------------------------------------------------
        // LOGIC 2: HTML5 VIDEO SCRUBBING
        // ---------------------------------------------------------
        else if (type === 'video') {
            const video = container.querySelector('.sifency-scrub-video');
            if (!video) return;

            // Wait for video metadata to load so we know the duration
            video.onloadedmetadata = function() {
                
                // Animate video's currentTime property
                gsap.to(video, {
                    currentTime: video.duration, // From 0 to end of video
                    ease: "none",
                    scrollTrigger: {
                        trigger: container,
                        start: "top top",
                        end: scrollLength,
                        scrub: true,
                        pin: true,
                    }
                });
            };

            // Force load to fetch metadata on mobile/safari
            video.load();
        }
    };

    $(window).on('elementor/frontend/init', function () {
        elementorFrontend.hooks.addAction(
            'frontend/element_ready/sifency-media-scrubbing.default',
            initMediaScrubbing
        );
    });

})(jQuery);