;(function($) {
    'use strict';

    /**
     * Initialize Video Gallery Widget
     */
    function initVideoGallery($scope) {
        const $wrapper = $scope.find('.unlockafe-video-gallery-wrapper');
        
        if ($wrapper.length === 0) {
            return;
        }

        const lightbox = $wrapper.data('lightbox') === 'yes';
        const autoplay = $wrapper.data('autoplay') === 'yes';
        const galleryLayout = $wrapper.data('layout') || 
                             ($wrapper.hasClass('unlockafe-gallery-carousel') ? 'carousel' : 
                             ($wrapper.hasClass('unlockafe-gallery-masonry') ? 'masonry' : 'grid'));
        const $lightbox = $scope.find('.unlockafe-video-lightbox');
        const $lightboxOverlay = $lightbox.find('.unlockafe-video-lightbox-overlay');
        const $lightboxContent = $lightbox.find('.unlockafe-video-lightbox-content');
        const $lightboxClose = $lightbox.find('.unlockafe-video-lightbox-close');
        const $lightboxPlayer = $lightbox.find('.unlockafe-video-lightbox-player');
        const $videoIframe = $lightbox.find('.unlockafe-video-iframe');
        const $playButtons = $wrapper.find('.unlockafe-video-play-button');
        
        // Initialize carousel if layout is carousel
        if (galleryLayout === 'carousel') {
            const itemsPerView = $wrapper.data('items-per-view') || 3;
            const itemsPerViewTablet = $wrapper.data('items-per-view-tablet') || 2;
            const itemsPerViewMobile = $wrapper.data('items-per-view-mobile') || 1;
            initCarousel($wrapper, {
                itemsPerView: itemsPerView,
                itemsPerViewTablet: itemsPerViewTablet,
                itemsPerViewMobile: itemsPerViewMobile
            });
        }

        // Open lightbox
        function openLightbox(videoUrl, videoType) {
            if (!lightbox || !$lightbox.length) {
                return;
            }

            // Build embed URL with autoplay if needed
            let embedUrl = videoUrl;
            if (autoplay) {
                if (videoType === 'youtube') {
                    embedUrl += (embedUrl.indexOf('?') > -1 ? '&' : '?') + 'autoplay=1';
                } else if (videoType === 'vimeo') {
                    embedUrl += (embedUrl.indexOf('?') > -1 ? '&' : '?') + 'autoplay=1';
                }
            }

            $videoIframe.attr('src', embedUrl);
            $lightbox.addClass('active');
            $('body').css('overflow', 'hidden'); // Prevent body scroll
        }

        // Close lightbox
        function closeLightbox() {
            $lightbox.removeClass('active');
            $videoIframe.attr('src', ''); // Stop video playback
            $('body').css('overflow', ''); // Restore body scroll
        }

        // Play button click
        $playButtons.on('click', function(e) {
            e.preventDefault();
            e.stopPropagation();
            
            const $button = $(this);
            const videoUrl = $button.data('video-url');
            const videoType = $button.data('video-type');

            if (lightbox) {
                openLightbox(videoUrl, videoType);
            } else {
                // Open in new tab/window
                if (videoType === 'youtube' || videoType === 'vimeo') {
                    // Extract original URL from embed URL
                    let originalUrl = '';
                    if (videoType === 'youtube') {
                        const videoId = videoUrl.match(/embed\/([^?]+)/);
                        if (videoId) {
                            originalUrl = 'https://www.youtube.com/watch?v=' + videoId[1];
                        }
                    } else if (videoType === 'vimeo') {
                        const videoId = videoUrl.match(/video\/(\d+)/);
                        if (videoId) {
                            originalUrl = 'https://vimeo.com/' + videoId[1];
                        }
                    }
                    if (originalUrl) {
                        window.open(originalUrl, '_blank');
                    }
                } else {
                    // Self-hosted video
                    window.open(videoUrl, '_blank');
                }
            }
        });

        // Close lightbox handlers
        if ($lightbox.length) {
            $lightboxClose.on('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                closeLightbox();
            });

            $lightboxOverlay.on('click', function(e) {
                if (e.target === this) {
                    closeLightbox();
                }
            });

            // Close on ESC key
            $(document).on('keydown.videoGallery', function(e) {
                if (e.key === 'Escape' && $lightbox.hasClass('active')) {
                    closeLightbox();
                }
            });
        }

        // Video item click (if whole item is clickable)
        $wrapper.find('.unlockafe-video-item').on('click', function(e) {
            if (!$(e.target).closest('.unlockafe-video-play-button').length) {
                const $item = $(this);
                const $playButton = $item.find('.unlockafe-video-play-button');
                if ($playButton.length) {
                    $playButton.trigger('click');
                }
            }
        });
    }

    /**
     * Initialize Carousel functionality
     */
    function initCarousel($wrapper, settings = {}) {
        const $carousel = $wrapper;
        const $items = $carousel.find('.unlockafe-video-item');
        
        if ($items.length === 0) {
            return;
        }
        
        // Get the parent widget container for navigation positioning
        const $widgetContainer = $carousel.closest('.elementor-widget-unlockafe-video-gallery');
        const $navContainer = $widgetContainer.length ? $widgetContainer : $carousel.parent();
        
        // Ensure navigation container has relative positioning
        if ($navContainer.length && $navContainer.css('position') === 'static') {
            $navContainer.css('position', 'relative');
        }

        // Get customizable items per view settings
        const itemsPerViewDesktop = settings.itemsPerView || parseInt($carousel.data('items-per-view')) || 3;
        const itemsPerViewTablet = settings.itemsPerViewTablet || parseInt($carousel.data('items-per-view-tablet')) || 2;
        const itemsPerViewMobile = settings.itemsPerViewMobile || parseInt($carousel.data('items-per-view-mobile')) || 1;

        // Calculate items per view based on container width and settings
        // Using standard responsive breakpoints:
        // Desktop: >= 992px (min-width: 992px)
        // Tablet: 768px - 991px (min-width: 768px)
        // Mobile: < 768px (max-width: 767px)
        function getItemsPerView() {
            const containerWidth = $carousel.width();
            if (containerWidth >= 992) {
                return itemsPerViewDesktop;
            } else if (containerWidth >= 768) {
                return itemsPerViewTablet;
            } else {
                return itemsPerViewMobile;
            }
        }

        // Set item width based on items per view
        function updateItemWidth() {
            const itemsPerView = getItemsPerView();
            const gap = 20; // Match CSS gap
            const itemWidth = `calc(${100 / itemsPerView}% - ${gap * (itemsPerView - 1) / itemsPerView}px)`;
            $items.css('width', itemWidth);
        }

        // Smooth scroll to item
        function scrollToItem(index, smooth = true) {
            const $targetItem = $items.eq(index);
            if (!$targetItem.length) return;
            
            // Calculate scroll position by summing widths of previous items
            let scrollPosition = 0;
            for (let i = 0; i < index; i++) {
                const $item = $items.eq(i);
                if ($item.length) {
                    scrollPosition += $item.outerWidth(true);
                }
            }
            
            // Ensure we don't scroll beyond bounds
            const carouselWidth = $carousel.width();
            const maxScroll = Math.max(0, $carousel[0].scrollWidth - carouselWidth);
            scrollPosition = Math.max(0, Math.min(scrollPosition, maxScroll));
            
            // Perform the scroll
            if (smooth) {
                $carousel.stop().animate({
                    scrollLeft: scrollPosition
                }, {
                    duration: 500,
                    easing: 'swing',
                    complete: function() {
                        // Force update index after scroll completes - use multiple methods to ensure accuracy
                        setTimeout(function() {
                            currentIndex = getCurrentIndex();
                            updateNavButtons();
                        }, 50);
                        
                        // Double check after animation fully settles
                        setTimeout(function() {
                            currentIndex = getCurrentIndex();
                        }, 200);
                    }
                });
            } else {
                $carousel.scrollLeft(scrollPosition);
                // Update index immediately after scroll
                requestAnimationFrame(function() {
                    currentIndex = getCurrentIndex();
                    updateNavButtons();
                });
            }
        }

        // Navigation arrows
        let currentIndex = 0;
        const totalItems = $items.length;
        let isScrolling = false;

        // Create navigation buttons if they don't exist (append to widget container, not carousel)
        let $nav = $navContainer.find('.unlockafe-carousel-nav');
        if ($nav.length === 0) {
            // Use both Font Awesome class and Unicode fallback
            $nav = $('<div class="unlockafe-carousel-nav"><button class="unlockafe-carousel-prev"><i class="fas fa-chevron-left"></i></button><button class="unlockafe-carousel-next"><i class="fas fa-chevron-right"></i></button></div>');
            $navContainer.append($nav);
        }

        const $prevBtn = $nav.find('.unlockafe-carousel-prev');
        const $nextBtn = $nav.find('.unlockafe-carousel-next');
        const $prevIcon = $prevBtn.find('i');
        const $nextIcon = $nextBtn.find('i');
        
        // Ensure navigation is visible on all devices (tablet and mobile)
        // Add classes to force visibility
        $nav.addClass('unlockafe-nav-visible');
        $prevBtn.addClass('unlockafe-arrow-visible');
        $nextBtn.addClass('unlockafe-arrow-visible');
        
        // Ensure icons are visible
        $prevIcon.css({
            'display': 'inline-block',
            'visibility': 'visible',
            'opacity': '1',
            'color': '#333'
        });
        
        $nextIcon.css({
            'display': 'inline-block',
            'visibility': 'visible',
            'opacity': '1',
            'color': '#333'
        });
        
        // Also set inline styles as fallback
        $nav.attr('style', 'display: block !important; visibility: visible !important; opacity: 1 !important;');
        $prevBtn.attr('style', 'display: flex !important; visibility: visible !important; opacity: 1 !important;');
        $nextBtn.attr('style', 'display: flex !important; visibility: visible !important; opacity: 1 !important;');

        // Calculate which item is currently in view (most visible)
        function getCurrentIndex() {
            if ($items.length === 0) return 0;
            
            const scrollLeft = $carousel.scrollLeft();
            const carouselWidth = $carousel.width();
            
            let currentIndex = 0;
            let maxVisibleArea = 0;
            let firstVisibleIndex = -1;
            
            $items.each(function(index) {
                const $item = $(this);
                let itemScrollLeft = 0;
                
                // Calculate cumulative width of previous items
                for (let i = 0; i < index; i++) {
                    itemScrollLeft += $items.eq(i).outerWidth(true);
                }
                
                const itemWidth = $item.outerWidth(true);
                const itemRight = itemScrollLeft + itemWidth;
                
                // Calculate visible area
                const visibleLeft = Math.max(scrollLeft, itemScrollLeft);
                const visibleRight = Math.min(scrollLeft + carouselWidth, itemRight);
                const visibleArea = Math.max(0, visibleRight - visibleLeft);
                
                // Track first visible item
                if (firstVisibleIndex === -1 && visibleArea > 0) {
                    firstVisibleIndex = index;
                }
                
                if (visibleArea > maxVisibleArea) {
                    maxVisibleArea = visibleArea;
                    currentIndex = index;
                }
            });
            
            // For carousel navigation, return the first visible item index
            // This ensures consistent behavior across different screen sizes
            if (firstVisibleIndex >= 0) {
                return firstVisibleIndex;
            }
            
            return currentIndex;
        }

        // Update navigation buttons (with infinite loop, buttons are never disabled)
        function updateNavButtons() {
            if (isScrolling) return;
            
            // With infinite loop, navigation buttons are always enabled
            // Remove disabled class if it exists
            $prevBtn.removeClass('disabled');
            $nextBtn.removeClass('disabled');
        }

        // Scroll by items with infinite loop (rotation) - one by one
        function scrollByItems(direction, smooth = true) {
            if (isScrolling) return;
            isScrolling = true;
            
            const itemsPerView = getItemsPerView();
            
            // Get fresh current index - always recalculate to ensure accuracy
            const currentIdx = getCurrentIndex();
            
            const maxIndex = Math.max(0, totalItems - itemsPerView);
            const lastVideoIndex = totalItems - 1;
            
            // Calculate target index with infinite loop (rotation) - scroll one video at a time
            let targetIndex;
            
            // Check if we're at the boundaries - get fresh scroll position every time
            const scrollLeft = $carousel.scrollLeft();
            const carouselWidth = $carousel.width();
            const totalScrollWidth = $carousel[0].scrollWidth;
            const isAtEnd = (scrollLeft + carouselWidth) >= (totalScrollWidth - 10); // 10px tolerance
            const isAtStart = scrollLeft <= 10; // 10px tolerance
            
            if (direction === 'next') {
                // Right arrow - move forward one video
                // Check if we've reached or passed the last video
                if (isAtEnd || (currentIdx + itemsPerView) >= totalItems) {
                    // At the last video, loop to the beginning (video 1 - index 0)
                    targetIndex = 0;
                } else {
                    // Move forward one video
                    targetIndex = Math.min(maxIndex, currentIdx + 1);
                }
            } else {
                // Left arrow - move backward (reverse direction)
                // Check if we're at the first video position (Video1 - index 0)
                const isAtVeryStart = scrollLeft <= 10;
                
                // Always check scroll position first for accurate detection
                if (isAtVeryStart) {
                    // At the very start (scroll position 0 or near 0)
                    // Loop to show the last video(s)
                    targetIndex = maxIndex;
                } else {
                    // Not at start - calculate target index based on current scroll position
                    // Find which item is currently at the left edge of the viewport
                    let leftEdgeItemIndex = 0;
                    let cumulativeWidth = 0;
                    
                    for (let i = 0; i < totalItems; i++) {
                        const $item = $items.eq(i);
                        const itemWidth = $item.outerWidth(true);
                        
                        if (scrollLeft >= cumulativeWidth - 5 && scrollLeft < cumulativeWidth + itemWidth + 5) {
                            leftEdgeItemIndex = i;
                            break;
                        }
                        
                        cumulativeWidth += itemWidth;
                    }
                    
                    // Go to previous item
                    if (leftEdgeItemIndex > 0) {
                        targetIndex = leftEdgeItemIndex - 1;
                    } else {
                        // Already at first item, loop to last
                        targetIndex = maxIndex;
                    }
                }
            }
            
            // Update currentIndex immediately to the target we're scrolling to
            // This ensures the next click uses the correct index
            currentIndex = targetIndex;
            
            // Use scrollToItem to scroll to the target
            scrollToItem(targetIndex, smooth);
            
            // Reset scrolling flag after animation - update happens in scrollToItem complete callback
            if (smooth) {
                setTimeout(function() {
                    // Verify and update index after animation completes
                    const verifiedIndex = getCurrentIndex();
                    // Use verified index if it's different and valid
                    if (verifiedIndex !== targetIndex && verifiedIndex >= 0 && verifiedIndex < totalItems) {
                        currentIndex = verifiedIndex;
                    } else {
                        currentIndex = targetIndex;
                    }
                    isScrolling = false;
                }, 600);
            } else {
                // Verify index for instant scroll
                const verifiedIndex = getCurrentIndex();
                if (verifiedIndex !== targetIndex && verifiedIndex >= 0 && verifiedIndex < totalItems) {
                    currentIndex = verifiedIndex;
                } else {
                    currentIndex = targetIndex;
                }
                isScrolling = false;
            }
        }

        // Previous button (with infinite loop)
        $prevBtn.off('click.videoGallery').on('click.videoGallery', function(e) {
            e.preventDefault();
            e.stopPropagation();
            
            if (isScrolling) return;
            
            scrollByItems('prev', true);
        });

        // Next button (with infinite loop)
        $nextBtn.off('click.videoGallery').on('click.videoGallery', function(e) {
            e.preventDefault();
            e.stopPropagation();
            
            if (isScrolling) return;
            
            scrollByItems('next', true);
        });

        // Update on scroll
        let scrollTimeout;
        $carousel.off('scroll.videoGallery').on('scroll.videoGallery', function() {
            if (isScrolling) return;
            
            clearTimeout(scrollTimeout);
            scrollTimeout = setTimeout(function() {
                currentIndex = getCurrentIndex();
                updateNavButtons();
            }, 150);
        });

        // Handle window resize - update item width and recalculate index when breakpoint changes
        let resizeTimeout;
        let lastBreakpoint = null;
        $(window).on('resize.videoGalleryCarousel', function() {
            clearTimeout(resizeTimeout);
            resizeTimeout = setTimeout(function() {
                const containerWidth = $carousel.width();
                let currentBreakpoint = 'mobile';
                if (containerWidth >= 992) {
                    currentBreakpoint = 'desktop';
                } else if (containerWidth >= 768) {
                    currentBreakpoint = 'tablet';
                }
                
                // Update item width
                updateItemWidth();
                
                // Recalculate current index if breakpoint changed
                if (lastBreakpoint !== null && lastBreakpoint !== currentBreakpoint) {
                    currentIndex = getCurrentIndex();
                }
                lastBreakpoint = currentBreakpoint;
                
                updateNavButtons();
            }, 250);
        });

        // Initialize
        updateItemWidth();
        // Wait for DOM to update
        setTimeout(function() {
            currentIndex = getCurrentIndex();
            updateNavButtons();
        }, 100);
        
        // Prevent arrow clicks from triggering video play
        $prevBtn.on('click', function(e) {
            e.stopPropagation();
        });
        
        $nextBtn.on('click', function(e) {
            e.stopPropagation();
        });
    }

    // Initialize on Elementor frontend
    $(window).on('elementor/frontend/init', function() {
        elementorFrontend.hooks.addAction('frontend/element_ready/unlockafe-video-gallery.default', function($scope) {
            initVideoGallery($scope);
        });
    });

    // Also initialize on document ready (for non-Elementor pages)
    $(document).ready(function() {
        $('.elementor-widget-unlockafe-video-gallery').each(function() {
            var $scope = $(this);
            initVideoGallery($scope);
        });
    });

    // Re-initialize on Elementor preview refresh
    if (typeof elementorFrontend !== 'undefined') {
        elementorFrontend.hooks.addAction('frontend/element_ready/global', function($scope) {
            if ($scope.find('.unlockafe-video-gallery-wrapper').length) {
                setTimeout(function() {
                    initVideoGallery($scope);
                }, 100);
            }
        });
    }

})(jQuery);


