(function ($) {
    "use strict";

    const initCinematicTypography = ($scope) => {
        const wrapper = $scope[0].querySelector('.sifency-typo-wrapper');
        if (!wrapper) return;

        const config = JSON.parse(wrapper.dataset.config || '{}');
        const pinWrap = wrapper.querySelector('.sifency-typo-pin');

        // Helper to grab Elementor's active breakpoint computed variables dynamically
        const getCssVar = (varName, defaultVal) => {
            const val = getComputedStyle(wrapper).getPropertyValue(varName).trim();
            return val !== '' ? parseFloat(val) : defaultVal;
        };

        // Handles Responsive Rows Visually 
        const updateRowsVisibility = () => {
            const repeatCount = getCssVar('--s-repeat-count', 5);
            const rows = wrapper.querySelectorAll('.sifency-bg-row');
            rows.forEach((row, index) => {
                row.style.display = index >= repeatCount ? 'none' : '';
            });
        };
        updateRowsVisibility();
        window.addEventListener('resize', updateRowsVisibility);

        // ==========================================
        // MODULE 1: Scroll Expansion (Mask Reveal)
        // ==========================================
        if (config.scroll && typeof ScrollTrigger !== 'undefined') {
            const maskWrap = wrapper.querySelector('.sifency-typo-mask');

            // Functional syntax dynamically updates during Screen Resize & Breakpoints change!
            gsap.fromTo(maskWrap,
                {
                    clipPath: () => `inset(${getCssVar('--s-start-clip', 35)}% 0% ${getCssVar('--s-start-clip', 35)}% 0%)`
                },
                {
                    clipPath: () => `inset(${getCssVar('--s-end-clip', 0)}% 0% ${getCssVar('--s-end-clip', 0)}% 0%)`,
                    ease: "none",
                    scrollTrigger: {
                        trigger: wrapper,
                        start: "top top",
                        end: () => `+=${getCssVar('--s-scroll-dur', 150)}%`,
                        pin: true,
                        scrub: true,
                        invalidateOnRefresh: true,
                    }
                }
            );
        }

        // ==========================================
        // MODULE 2: Hover Effect (Proximity Stretch)
        // ==========================================
        if (config.hover) {
            const chars = wrapper.querySelectorAll('.sifency-char-inner');
            const isTouch = window.matchMedia("(pointer: coarse)").matches;

            if (!isTouch) {
                wrapper.addEventListener('mousemove', (e) => {
                    const mouseX = e.clientX;
                    const mouseY = e.clientY;

                    // Automatically evaluates the live scale based on current device screen
                    const currentScale = getCssVar('--s-hover-scale', 1.8);
                    const currentRadius = getCssVar('--s-hover-radius', 200);

                    chars.forEach(charInner => {
                        const rect = charInner.getBoundingClientRect();
                        const charCenterX = rect.left + rect.width / 2;
                        const charCenterY = rect.top + rect.height / 2;

                        const distance = Math.sqrt(Math.pow(mouseX - charCenterX, 2) + Math.pow(mouseY - charCenterY, 2));

                        if (distance < currentRadius) {
                            const proximity = 1 - (distance / currentRadius);
                            const scaleVal = 1 + (proximity * (currentScale - 1));

                            gsap.to(charInner, {
                                scaleY: scaleVal,
                                duration: 0.2,
                                ease: "power2.out",
                                transformOrigin: "center center",
                                overwrite: "auto"
                            });
                        } else {
                            gsap.to(charInner, { scaleY: 1, duration: 0.4, ease: "power2.out", overwrite: "auto" });
                        }
                    });
                });

                wrapper.addEventListener('mouseleave', () => {
                    gsap.to(chars, { scaleY: 1, duration: 0.6, ease: "elastic.out(1, 0.4)", overwrite: "auto" });
                });
            }
        }

        // ==========================================
        // MODULE 3: Premium 3D Perspective Flip
        // ==========================================
        if (config.flip) {
            const flipChars = wrapper.querySelectorAll('.sifency-is-flipping .sifency-char-inner');
            const axis = config.axis || 'rotateY';

            gsap.set('.sifency-bg-row', { perspective: 1200 });

            let currentFlipDur = getCssVar('--s-flip-dur', 4);
            let flipTimelines = [];

            const initFlips = () => {
                flipTimelines.forEach(tl => tl.kill());
                flipTimelines = [];

                flipChars.forEach(charInner => {
                    gsap.set(charInner, { transformStyle: "preserve-3d", transformOrigin: "center center" });

                    const tl = gsap.timeline({ repeat: -1 });
                    tl.to(charInner, {
                        [axis]: 360,
                        duration: currentFlipDur,
                        ease: "none"
                    }, 0);

                    const tlBright = gsap.to(charInner, {
                        filter: "brightness(0.3)",
                        duration: currentFlipDur / 4,
                        yoyo: true,
                        repeat: -1,
                        ease: "power1.inOut"
                    });

                    flipTimelines.push(tl, tlBright);
                });
            };

            initFlips();

            // Re-evaluates timeline duration speed smoothly when users swap device breakpoints
            window.addEventListener('resize', () => {
                const newDur = getCssVar('--s-flip-dur', 4);
                if (newDur !== currentFlipDur) {
                    currentFlipDur = newDur;
                    initFlips();
                }
            });
        }
    };

    $(window).on('elementor/frontend/init', function () {
        elementorFrontend.hooks.addAction(
            'frontend/element_ready/sifency-addons-interactive-typography.default',
            initCinematicTypography
        );
    });

})(jQuery);