(($) => {
    "use strict";

    // --- Part 1: Sticky Projects Stack ---
    const initStickyProjectsStack = ($scope) => {
        const wrapper = $scope[0].querySelector('.sifency-portfolio-wrapper');
        const items = Array.from($scope[0].querySelectorAll('.sifency-portfolio-item'));

        if (!wrapper || !items.length) return;

        const isEnabled = wrapper.dataset.stickyEnabled === 'yes';
        const scaleDensity = parseFloat(wrapper.dataset.scaleDensity) || 0.2;
        const opacityDensity = parseFloat(wrapper.dataset.opacityDensity) || 0.3;

        // Cleanup function for disabled state
        if (!isEnabled) {
            items.forEach(item => {
                Object.assign(item.style, {
                    position: '', top: '', zIndex: '', transform: 'scale(1)', opacity: '1'
                });
            });
            window.removeEventListener('scroll', window.sifencyScrollHandler);
            return;
        }

        // Allow visible overflow on parent containers
        $scope.parents().css('overflow', 'visible');

        const stickyOffset = 80;
        const staggerAmount = 30;

        // Set initial sticky positions natively
        items.forEach((item, index) => {
            Object.assign(item.style, {
                position: 'sticky',
                top: `${stickyOffset + (index * staggerAmount)}px`,
                zIndex: index + 1
            });
        });

        // Optimized Scroll Listener using RequestAnimationFrame
        let isTicking = false;

        // Remove previous listener if it exists to prevent duplicates
        if (window.sifencyScrollHandler) {
            window.removeEventListener('scroll', window.sifencyScrollHandler);
        }

        window.sifencyScrollHandler = () => {
            if (!isTicking) {
                window.requestAnimationFrame(() => {
                    items.forEach((item, index) => {
                        if (index === items.length - 1) return;

                        const rect = item.getBoundingClientRect();
                        const nextRect = items[index + 1].getBoundingClientRect();

                        if (nextRect.top < rect.bottom && nextRect.top > 0) {
                            const progress = (rect.bottom - nextRect.top) / rect.height;
                            const scale = 1 - (progress * scaleDensity);
                            const opacity = 1 - (progress * opacityDensity);

                            item.style.transform = `scale(${scale})`;
                            item.style.opacity = opacity;
                        } else if (nextRect.top >= rect.bottom) {
                            item.style.transform = 'scale(1)';
                            item.style.opacity = '1';
                        }
                    });
                    isTicking = false;
                });
                isTicking = true;
            }
        };

        // Passive event listener for better scrolling performance
        window.addEventListener('scroll', window.sifencyScrollHandler, { passive: true });
    };

    // --- Elementor Init ---
    $(window).on('elementor/frontend/init', () => {
        elementorFrontend.hooks.addAction('frontend/element_ready/sifency-addons-projects.default', initStickyProjectsStack);
    });

})(jQuery);


// --- Part 2: Hover Reveal Image ---
document.addEventListener('DOMContentLoaded', () => {
    "use strict";

    const mouse = { x: 0, y: 0 };
    const pos = { x: 0, y: 0 };
    const speed = 0.02;

    let activeItem = null;
    let imgEl = null;

    const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
    const lerp = (start, end, factor) => start + (end - start) * factor;

    const updateHoverImagePosition = () => {
        if (!activeItem || !imgEl) return;

        const rect = activeItem.getBoundingClientRect();

        // Calculate offset including current scroll position
        const offsetX = rect.left + window.scrollX;
        const offsetY = rect.top + window.scrollY;

        // Smooth follow (Lerp)
        pos.x = lerp(pos.x, mouse.x, speed);
        pos.y = lerp(pos.y, mouse.y, speed);

        const x = clamp(pos.x - offsetX, 0, rect.width);
        const y = clamp(pos.y - offsetY, 0, rect.height);

        // Rotation
        const rotate = (mouse.x - pos.x) * 0.05;

        // Direct DOM manipulation for buttery smooth 60fps
        imgEl.style.transform = `translate3d(${x}px, ${y}px, 0) scale(1) rotate(${rotate}deg)`;
    };

    // Animation loop
    const animate = () => {
        updateHoverImagePosition();
        requestAnimationFrame(animate);
    };
    animate();

    // Event Delegation for hover items (Better for dynamically loaded Elementor content)
    document.body.addEventListener('mouseenter', (e) => {
        const item = e.target.closest('.sifency-portfolio-style-3 .sifency-portfolio-item');
        if (!item) return;

        activeItem = item;

        // Reset siblings z-index, elevate active
        document.querySelectorAll('.sifency-portfolio-style-3 .sifency-portfolio-item')
            .forEach(el => el.style.zIndex = '1');
        activeItem.style.zIndex = '99';

        imgEl = activeItem.querySelector('.sifency-hover-reveal-img');

        pos.x = mouse.x;
        pos.y = mouse.y;

        if (imgEl) {
            imgEl.style.opacity = '1';
            imgEl.style.transform = 'translate3d(0,0,0) scale(0)';

            // Allow browser to register the 0 scale before animating to 1
            requestAnimationFrame(() => {
                imgEl.style.transform = 'translate3d(0,0,0) scale(1)';
            });
        }
    }, true); // Use capturing phase for mouseenter

    document.body.addEventListener('mousemove', (e) => {
        mouse.x = e.pageX;
        mouse.y = e.pageY;
    }, { passive: true });

    document.body.addEventListener('mouseleave', (e) => {
        const item = e.target.closest('.sifency-portfolio-style-3 .sifency-portfolio-item');
        if (!item) return;

        if (imgEl) {
            imgEl.style.opacity = '0';
            imgEl.style.transform = 'scale(0)';
        }

        item.style.zIndex = '1';
        activeItem = null;
        imgEl = null;
    }, true);
});