(function ($) {
    "use strict";

    var PlusFlipBox = function ($scope, $) {
        var $advancedFlipbox = $scope.find('.tp-flipbox-advanced');

        if (!$advancedFlipbox.length) return;

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

        var $normalMode = $advancedFlipbox.filter('.flipbox-advanced-normal');
        if ($normalMode.length) {
            $normalMode.each(function () {
                var $container = $(this);
                var $innerLoop = $container.find('.post-inner-loop');
                var $scene = $container.find('.tp-flipbox-scene');
                var $card = $container.find('.tp-flipbox-card');
                var $front = $container.find('.tp-flipbox-face-front');
                var $back = $container.find('.tp-flipbox-face-back');

                // Surgical 3D preservation: Only target this widget's specific path
                var $toPreserve = $container.add($innerLoop).add($scene).add($card);

                // Find specifically the Magic Scroll parent or Widget container for this widget
                var $magicScrollParent = $container.closest('.tp-magic-scroll');
                var $widgetContainer = $container.closest('.elementor-widget-container');

                $toPreserve = $toPreserve.add($magicScrollParent).add($widgetContainer).add($scope);

                // For large rotations (past 90 deg), we need high perspective and visible overflow
                gsap.set($toPreserve, {
                    transformStyle: "preserve-3d",
                    overflow: "visible" // Critical: prevent clipping during deep 3D rotation
                });

                // Apply high perspective to the Magic Scroll parent to allow deep rotation
                if ($magicScrollParent.length) {
                    gsap.set($magicScrollParent, { perspective: 2000 });
                }

                // Physical Z-axis separation (Front forward, Back backward)
                // We use a small translation to maintain 3D order without distortion
                gsap.set($front, { rotationY: 0, z: 1, backfaceVisibility: "hidden" });
                gsap.set($back, { rotationY: 180, z: -1, backfaceVisibility: "hidden" });
            });
        }

        // 2. Advanced Repeater Mode
        var $repeaterMode = $advancedFlipbox.filter('.flipbox-advanced-repeater');
        if ($repeaterMode.length) {
            $repeaterMode.each(function () {
                var $container = $(this);
                var $wrapper = $container.find('.tp-flipbox-advanced-wrapper');
                var $items = $container.find('.tp-flipbox-adv-item');

                if ($items.length <= 1) return;

                var rotateType = $wrapper.attr('data-rotate-type') || 'vertical';
                var scrollTriggerStart = $wrapper.attr('data-scroll-trigger') || 'top center';
                var isSticky = $wrapper.attr('data-sticky') === 'yes' ? true : false;
                var scrollDuration = $wrapper.attr('data-scroll-duration') || 100;
                var flipDirection = $wrapper.attr('data-flip-direction') || 'forward';
                var transformOrigin = $wrapper.attr('data-transform-origin') || 'center center';

                // Initial styles to stack the items & prevent width jump by explicitly declaring "100%"
                gsap.set($container, { width: "100%", display: "block", perspective: 1500 });
                gsap.set($wrapper, { position: "relative", width: "100%", display: "block", perspective: 1500, transformStyle: "preserve-3d" });

                // Stack items on top of each other securely
                $items.each(function (i, item) {
                    if (i === 0) {
                        gsap.set(item, { position: "relative", zIndex: $items.length - i, backfaceVisibility: "hidden" });
                    } else {
                        gsap.set(item, { position: "absolute", top: 0, left: 0, zIndex: $items.length - i, autoAlpha: 0, backfaceVisibility: "hidden", rotationX: 0, rotationY: 0 });
                    }
                });

                // Pin the scope, avoiding the left/right "jerk" positioning issues
                if (isSticky) {
                    $scope[0].style.setProperty('transition', 'none', 'important');
                }

                var tl = gsap.timeline({
                    scrollTrigger: {
                        trigger: $scope[0],
                        start: scrollTriggerStart,
                        end: "+=" + ($items.length * scrollDuration) + "%", // scroll duration based on items count
                        scrub: 1,
                        pin: isSticky ? $scope[0] : false, // Pin scope directly
                        pinSpacing: true
                    }
                });

                $items.each(function (i, item) {
                    if (i === 0) return; // skip first, it's already shown

                    var $prevItem = $items.eq(i - 1);
                    var $currItem = $(item);

                    var prevRotVal = -90;
                    var nextRotVal = 90;

                    if (flipDirection === 'reverse') {
                        prevRotVal = 90;
                        nextRotVal = -90;
                    }

                    if (rotateType === 'vertical') {
                        // Sequential rotate out/in without opacity fade
                        tl.to($prevItem, { rotationX: prevRotVal, transformOrigin: transformOrigin, duration: 1, ease: "none" })
                            .set($prevItem, { autoAlpha: 0 }) // Instantly hide
                            .set($currItem, { autoAlpha: 1, rotationX: nextRotVal, transformOrigin: transformOrigin }) // Instantly show behind
                            .to($currItem, { rotationX: 0, duration: 1, ease: "none" });
                    } else {
                        // Sequential rotate out/in without opacity fade
                        tl.to($prevItem, { rotationY: prevRotVal, transformOrigin: transformOrigin, duration: 1, ease: "none" })
                            .set($prevItem, { autoAlpha: 0 }) // Instantly hide
                            .set($currItem, { autoAlpha: 1, rotationY: nextRotVal, transformOrigin: transformOrigin }) // Instantly show behind
                            .to($currItem, { rotationY: 0, duration: 1, ease: "none" });
                    }
                });
            });
        }
    };

    $(window).on('elementor/frontend/init', function () {
        elementorFrontend.hooks.addAction('frontend/element_ready/tp-flip-box.default', PlusFlipBox);
    });

})(jQuery);
