(function ($) {
    "use strict";

    // Lightweight Custom Text Splitter
    const splitTextToSpans = (element, splitType) => {
        const text = element.innerText.trim();
        element.innerHTML = '';
        
        // Split by spaces to get words
        const words = text.split(/\s+/);
        
        words.forEach(word => {
            const wordSpan = document.createElement('span');
            wordSpan.className = 'sifency-reveal-word';
            
            if (splitType === 'char') {
                const chars = word.split('');
                chars.forEach(char => {
                    const charSpan = document.createElement('span');
                    charSpan.className = 'sifency-reveal-char';
                    charSpan.innerText = char;
                    wordSpan.appendChild(charSpan);
                });
            } else {
                wordSpan.innerText = word;
            }
            
            element.appendChild(wordSpan);
            
            // Add a space after each word except the last one to maintain natural spacing
            element.appendChild(document.createTextNode(' '));
        });
    };

    const initTextReveal = ($scope) => {
        const textElement = $scope.find('.sifency-text-reveal')[0];
        if (!textElement) return;

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

        // Get Data Attributes
        const splitType = textElement.dataset.split || 'word';
        const effectType = textElement.dataset.effect || 'fade';
        const inactiveOpacity = parseFloat(textElement.dataset.opacity || 0.2);

        // 1. Split the text into DOM elements
        splitTextToSpans(textElement, splitType);

        // 2. Select elements to animate based on Split Type
        const targetClass = splitType === 'char' ? '.sifency-reveal-char' : '.sifency-reveal-word';
        const targets = textElement.querySelectorAll(targetClass);

        if (targets.length === 0) return;

        // 3. Define the Animation Setup
        let fromVars = {
            opacity: inactiveOpacity
        };
        
        // Add Slide Up effect if chosen
        if (effectType === 'slideUp') {
            fromVars.y = 30; // 30px down initially
            fromVars.rotationX = -20; // Slight 3D rotation for modern feel
        }

        let toVars = {
            opacity: 1,
            y: 0,
            rotationX: 0,
            ease: "none",
            stagger: 0.1, // Delays animation between each word/char
            scrollTrigger: {
                trigger: textElement,
                start: "top 85%",    // Animation starts when element hits 85% of screen
                end: "bottom 50%",   // Finishes exactly when element is at center
                scrub: 1,            // Ties animation to scrollbar (Perfect with Lenis)
            }
        };

        // If 'Slide Up' is used, add force3D for better rendering
        if (effectType === 'slideUp') {
            gsap.set(targets, { transformOrigin: "0% 50%", force3D: true });
        }

        // 4. Run the GSAP Animation
        gsap.fromTo(targets, fromVars, toVars);
    };

    $(window).on('elementor/frontend/init', function () {
        const widgets = [
            'sifency-text-reveal.default',
            'sifency-atomic-text-reveal.default',
        ];
        $.each(widgets, function (index, widgetName) {
            elementorFrontend.hooks.addAction('frontend/element_ready/' + widgetName, initTextReveal);
        });
    });

})(jQuery);