// LS Stock Portfolio frontend logic.
// Configuration is passed from PHP via wp_localize_script() into window.lsSpConfig.
var lsSpAjaxUrl = (window.lsSpConfig && window.lsSpConfig.ajaxUrl) ? window.lsSpConfig.ajaxUrl : '';
var lsSpNonce   = (window.lsSpConfig && window.lsSpConfig.nonce) ? window.lsSpConfig.nonce : '';
var lsSpI18n    = (window.lsSpConfig && window.lsSpConfig.i18n) ? window.lsSpConfig.i18n : {
    more: 'Load more images',
    loading: 'Loading…',
    noMore: 'No more images',
    error: 'Error loading images'
};

var lsSpSlideshowInterval = (window.lsSpConfig && typeof window.lsSpConfig.slideshowInterval !== 'undefined')
    ? parseInt(window.lsSpConfig.slideshowInterval, 10)
    : 4000;
if (isNaN(lsSpSlideshowInterval) || lsSpSlideshowInterval < 500) {
    lsSpSlideshowInterval = 4000;
}
var lsSpIsPro = !!(window.lsSpConfig && window.lsSpConfig.isPro);

var lsSpTheme = (window.lsSpConfig && window.lsSpConfig.lightboxTheme) ? window.lsSpConfig.lightboxTheme : 'default';
var lsSpAnimation = (window.lsSpConfig && window.lsSpConfig.lightboxAnimation) ? window.lsSpConfig.lightboxAnimation : 'default';
var lsSpAnimDuration = (window.lsSpConfig && typeof window.lsSpConfig.lightboxAnimationDuration !== 'undefined')
    ? parseInt(window.lsSpConfig.lightboxAnimationDuration, 10)
    : 600;
if (isNaN(lsSpAnimDuration) || lsSpAnimDuration < 100) {
    lsSpAnimDuration = 600;
}

console.log('LS SP config:', window.lsSpConfig);
console.log('LS SP animation:', lsSpAnimation);

(function () {
    'use strict';

    // Ensure theme/global button icons don't interfere with our custom play button.
    (function injectLsSpPlayButtonStyles() {
        var style = document.createElement('style');
        style.type = 'text/css';
        style.textContent = '#ls-sp-lightbox .ls-sp-play-toggle::before,#ls-sp-lightbox .ls-sp-play-toggle::after{content:none !important;}';
        document.head.appendChild(style);
    })();

    console.log('[LS Stock Portfolio] frontend.js loaded', lsSpAjaxUrl, lsSpNonce, lsSpI18n);

    var lsSpGalleryLinks = [];
    var lsSpCurrentIndex = -1;
    var lsSpPrevIndex    = -1;
    var lsSpSlideshowTimer = null;
    var lsSpLightboxOverlay = null;
    var lsSpLightboxClickBound = false;

    function lsSpBuildGallery() {
        var links = document.querySelectorAll('.ls-sp-grid a.ls-sp-link');
        lsSpGalleryLinks = Array.prototype.slice.call(links);
        for (var i = 0; i < lsSpGalleryLinks.length; i++) {
            lsSpGalleryLinks[i].setAttribute('data-ls-sp-index', String(i));
        }
    }

    function lsSpEnsureLightbox() {
        if (lsSpLightboxOverlay) {
            return lsSpLightboxOverlay;
        }

        var overlay = document.createElement('div');
        overlay.id = 'ls-sp-lightbox';
        overlay.style.position = 'fixed';
        overlay.style.zIndex = '99999';
        overlay.style.top = '0';
        overlay.style.left = '0';
        overlay.style.width = '100%';
        overlay.style.height = '100%';
        overlay.style.background = 'rgba(0,0,0,0.9)';
        overlay.style.display = 'none';
        overlay.style.alignItems = 'center';
        overlay.style.justifyContent = 'center';

        var frame = document.createElement('div');
        frame.style.background = '#ffffff';
        frame.style.borderRadius = '6px';
        frame.style.maxWidth = '90vw';
        frame.style.maxHeight = '90vh';
        frame.style.boxShadow = '0 0 30px rgba(0,0,0,0.6)';
        frame.style.display = 'flex';
        frame.style.flexDirection = 'column';
        frame.style.overflow = 'hidden';
        frame.style.position = 'relative';
        overlay.appendChild(frame);

        // Apply fullscreen layout if the theme is set to "fullscreen".
        if (lsSpTheme === 'fullscreen') {
            // Let the overlay and frame fill the entire viewport without margins.
            overlay.style.alignItems = 'stretch';
            overlay.style.justifyContent = 'stretch';

            frame.style.maxWidth = '100vw';
            frame.style.maxHeight = '100vh';
            frame.style.width = '100%';
            frame.style.height = '100%';
            frame.style.borderRadius = '0';
            frame.style.background = '#000';
        }

        var imgWrapper = document.createElement('div');
        imgWrapper.style.flex = '1 1 auto';
        imgWrapper.style.display = 'flex';
        imgWrapper.style.alignItems = 'center';
        imgWrapper.style.justifyContent = 'center';
        imgWrapper.style.background = '#000';
        frame.appendChild(imgWrapper);

        var img = document.createElement('img');
        img.style.width = 'auto';
        img.style.height = 'auto';
        img.style.maxWidth = '100%';
        img.style.maxHeight = '100%';
        img.style.objectFit = 'contain';
        imgWrapper.appendChild(img);

        var caption = document.createElement('div');
        caption.id = 'ls-sp-lightbox-caption';
        caption.style.padding = '8px 12px';
        caption.style.fontSize = '12px';
        caption.style.color = '#444';
        caption.style.background = '#fff';
        caption.style.textAlign = 'center';
        frame.appendChild(caption);

        // Filmstrip thumbnail strip (used when lsSpTheme === "filmstrip").
        var thumbs = document.createElement('div');
        thumbs.className = 'ls-sp-thumbs';
        thumbs.style.flex = '0 0 auto';
        thumbs.style.display = 'none'; // only shown for Filmstrip
        thumbs.style.overflowX = 'auto';
        thumbs.style.whiteSpace = 'nowrap';
        thumbs.style.background = '#111';
        thumbs.style.padding = '6px 8px';
        thumbs.style.gap = '6px';
        thumbs.style.boxSizing = 'border-box';
        thumbs.style.textAlign = 'left';
        frame.appendChild(thumbs);

	// Carousel navigation dots (used when lsSpTheme === "carousel").
        var dots = document.createElement('div');
        dots.className = 'ls-sp-dots';
        dots.style.flex = '0 0 auto';
        dots.style.display = 'none';
        dots.style.padding = '6px 8px';
        dots.style.background = '#111';
        dots.style.textAlign = 'center';
        frame.appendChild(dots);

        var closeBtn = document.createElement('button');
        closeBtn.innerHTML = '&times;';
        closeBtn.setAttribute('type', 'button');
        closeBtn.style.position = 'absolute';
        closeBtn.style.top = '8px';
        closeBtn.style.right = '10px';
        closeBtn.style.border = 'none';
        closeBtn.style.background = 'transparent';
        closeBtn.style.fontSize = '24px';
        closeBtn.style.cursor = 'pointer';
        closeBtn.style.color = '#fff';
        closeBtn.style.textShadow = '0 0 6px rgba(0,0,0,0.7)';
        overlay.appendChild(closeBtn);

        var prevBtn = document.createElement('button');
        prevBtn.innerHTML = '&#10094;';
        prevBtn.setAttribute('type', 'button');
        prevBtn.style.position = 'absolute';
        prevBtn.style.left = '20px';
        prevBtn.style.top = '50%';
        prevBtn.style.transform = 'translateY(-50%)';
        prevBtn.style.border = 'none';
        prevBtn.style.width = '40px';
        prevBtn.style.height = '40px';
        prevBtn.style.borderRadius = '20px';
        prevBtn.style.cursor = 'pointer';
        prevBtn.style.background = 'rgba(255,255,255,0.85)';
        prevBtn.style.color = '#000';
        prevBtn.style.fontSize = '22px';
        prevBtn.style.display = 'flex';
        prevBtn.style.alignItems = 'center';
        prevBtn.style.justifyContent = 'center';
        overlay.appendChild(prevBtn);

        var nextBtn = document.createElement('button');
        nextBtn.innerHTML = '&#10095;';
        nextBtn.setAttribute('type', 'button');
        nextBtn.style.position = 'absolute';
        nextBtn.style.right = '20px';
        nextBtn.style.top = '50%';
        nextBtn.style.transform = 'translateY(-50%)';
        nextBtn.style.border = 'none';
        nextBtn.style.width = '40px';
        nextBtn.style.height = '40px';
        nextBtn.style.borderRadius = '20px';
        nextBtn.style.cursor = 'pointer';
        nextBtn.style.background = 'rgba(255,255,255,0.85)';
        nextBtn.style.color = '#000';
        nextBtn.style.fontSize = '22px';
        nextBtn.style.display = 'flex';
        nextBtn.style.alignItems = 'center';
        nextBtn.style.justifyContent = 'center';
        overlay.appendChild(nextBtn);

        var playBtn = document.createElement('div');
        playBtn.className = 'ls-sp-play-toggle';
        playBtn.setAttribute('role', 'button');
        playBtn.setAttribute('tabindex', '0');
        playBtn.style.position = 'absolute';
        playBtn.style.bottom = '24px';
        playBtn.style.left = '50%';
        playBtn.style.transform = 'translateX(-50%)';
        playBtn.style.border = 'none';
        playBtn.style.width = '60px';
        playBtn.style.height = '34px';
        playBtn.style.borderRadius = '17px'; // pill shape
        playBtn.style.cursor = 'pointer';
        playBtn.style.background = '#ffffff'; // white pill
        playBtn.style.color = '#000000';
        playBtn.style.display = 'flex';
        playBtn.style.alignItems = 'center';
        playBtn.style.justifyContent = 'center';
        playBtn.style.boxShadow = '0 0 8px rgba(0,0,0,0.35)';
        playBtn.style.padding = '0';
        playBtn.style.outline = 'none';

        // Play icon (triangle) drawn with borders, no emoji
        var playIcon = document.createElement('span');
        playIcon.style.display = 'block';
        playIcon.style.width = '0';
        playIcon.style.height = '0';
        playIcon.style.borderTop = '7px solid transparent';
        playIcon.style.borderBottom = '7px solid transparent';
        playIcon.style.borderLeft = '12px solid #000000';
        playBtn.appendChild(playIcon);

        overlay._playIcon = playIcon;
        overlay.appendChild(playBtn);

        overlay.addEventListener('click', function (e) {
            if (e.target === overlay) {
                lsSpCloseLightbox();
            }
        });

        closeBtn.addEventListener('click', function (e) {
            e.stopPropagation();
            lsSpCloseLightbox();
        });

        prevBtn.addEventListener('click', function (e) {
            e.stopPropagation();
            lsSpShowPrev();
        });

        nextBtn.addEventListener('click', function (e) {
            e.stopPropagation();
            lsSpShowNext();
        });

        playBtn.addEventListener('click', function (e) {
            e.stopPropagation();
            lsSpToggleSlideshow();
        });

        document.addEventListener('keydown', function (e) {
            if (overlay.style.display !== 'flex') {
                return;
            }
            if (e.key === 'Escape') {
                lsSpCloseLightbox();
            } else if (e.key === 'ArrowLeft') {
                lsSpShowPrev();
            } else if (e.key === 'ArrowRight') {
                lsSpShowNext();
            }
        });

        document.body.appendChild(overlay);

        overlay._img = img;
        overlay._caption = caption;
        overlay._playBtn = playBtn;
        overlay._thumbs = thumbs;
        overlay._dots = dots;

        lsSpLightboxOverlay = overlay;
        return overlay;
    }

    function lsSpCloseLightbox() {
        var overlay = lsSpEnsureLightbox();
        overlay.style.display = 'none';
        if (overlay._img) {
            overlay._img.src = '';
        }
        if (lsSpSlideshowTimer) {
            clearInterval(lsSpSlideshowTimer);
            lsSpSlideshowTimer = null;
        }
        lsSpCurrentIndex = -1;

        // Reset play button to default "play" state
        if (overlay._playBtn) {
            overlay._playBtn.setAttribute('data-state', 'paused');
        }
        if (overlay._playIcon) {
            var icon = overlay._playIcon;
            icon.style.width = '0';
            icon.style.height = '0';
            icon.style.borderTop = '7px solid transparent';
            icon.style.borderBottom = '7px solid transparent';
            icon.style.borderLeft = '12px solid #000000';
            icon.style.borderRight = 'none';
            icon.style.background = 'transparent';
            icon.style.boxShadow = 'none';
        }

        // Hide and clear the thumbnail strip when closing the lightbox.
        if (overlay._thumbs) {
            overlay._thumbs.style.display = 'none';
            overlay._thumbs.innerHTML = '';
        }
        // Hide and clear carousel dots when closing the lightbox.
        if (overlay._dots) {
            overlay._dots.style.display = 'none';
            overlay._dots.innerHTML = '';
        }
    }

        function lsSpInitFilmstrip(overlay) {
        if (!overlay || !overlay._thumbs) {
            return;
        }

        // Only enable the thumbnail strip if the theme is set to "filmstrip".
        if (lsSpTheme !== 'filmstrip') {
            overlay._thumbs.style.display = 'none';
            overlay._thumbs.innerHTML = '';
            return;
        }

        // Ensure we have gallery links to work with.
        if (!lsSpGalleryLinks || !lsSpGalleryLinks.length) {
            overlay._thumbs.style.display = 'none';
            overlay._thumbs.innerHTML = '';
            return;
        }

        overlay._thumbs.style.display = 'flex';
        overlay._thumbs.style.alignItems = 'center';

        // Rebuild the thumbnail strip every time we show an image, so it stays in sync with the gallery.
        overlay._thumbs.innerHTML = '';

        for (var i = 0; i < lsSpGalleryLinks.length; i++) {
            var link = lsSpGalleryLinks[i];
            if (!link) {
                continue;
            }

            var imgEl = link.querySelector('img');
            var thumbSrc = imgEl ? imgEl.getAttribute('src') : link.getAttribute('href');

            if (!thumbSrc) {
                continue;
            }

            var thumb = document.createElement('img');
            thumb.className = 'ls-sp-thumb';
            thumb.src = thumbSrc;
            thumb.setAttribute('data-ls-sp-index', String(i));
            thumb.style.width = '56px';
            thumb.style.height = 'auto';
            thumb.style.marginRight = '6px';
            thumb.style.borderRadius = '4px';
            thumb.style.cursor = 'pointer';
            thumb.style.boxSizing = 'border-box';
            thumb.style.opacity = (i === lsSpCurrentIndex) ? '1' : '0.5';
            thumb.style.border = (i === lsSpCurrentIndex) ? '2px solid #ffffff' : '2px solid transparent';

            thumb.addEventListener('click', function (e) {
                e.stopPropagation();
                var idxAttr = this.getAttribute('data-ls-sp-index') || '0';
                var idx = parseInt(idxAttr, 10);
                if (!isNaN(idx)) {
                    lsSpShowIndex(idx);
                }
            });

            overlay._thumbs.appendChild(thumb);
        }
    }
	    function lsSpInitCarousel(overlay) {
        if (!overlay || !overlay._dots) {
            return;
        }

        // Only enable the dots if the theme is set to "carousel".
        if (lsSpTheme !== 'carousel') {
            overlay._dots.style.display = 'none';
            overlay._dots.innerHTML = '';
            return;
        }

        // Ensure we have gallery links to work with.
        if (!lsSpGalleryLinks || !lsSpGalleryLinks.length) {
            overlay._dots.style.display = 'none';
            overlay._dots.innerHTML = '';
            return;
        }

        overlay._dots.style.display = 'flex';
        overlay._dots.style.alignItems = 'center';
        overlay._dots.style.justifyContent = 'center';
        overlay._dots.style.gap = '6px';

        // Rebuild the dots every time we show an image.
        overlay._dots.innerHTML = '';

        for (var i = 0; i < lsSpGalleryLinks.length; i++) {
            var dot = document.createElement('button');
            dot.type = 'button';
            dot.className = 'ls-sp-dot';
            dot.setAttribute('data-ls-sp-index', String(i));
            dot.style.width = '10px';
            dot.style.height = '10px';
            dot.style.borderRadius = '50%';
            dot.style.border = 'none';
            dot.style.padding = '0';
            dot.style.cursor = 'pointer';
            dot.style.background = (i === lsSpCurrentIndex) ? '#ffffff' : '#555555';

            dot.addEventListener('click', function (e) {
                e.stopPropagation();
                var idxAttr = this.getAttribute('data-ls-sp-index') || '0';
                var idx = parseInt(idxAttr, 10);
                if (!isNaN(idx)) {
                    lsSpShowIndex(idx);
                }
            });

            overlay._dots.appendChild(dot);
        }
    }

    function lsSpShowIndex(index) {
        if (!lsSpGalleryLinks.length) {
            return;
        }
        if (index < 0) {
            index = lsSpGalleryLinks.length - 1;
        }
        if (index >= lsSpGalleryLinks.length) {
            index = 0;
        }

        // Remember previous index for directional animations.
        var previousIndex = lsSpCurrentIndex;
        lsSpCurrentIndex = index;

        var link = lsSpGalleryLinks[lsSpCurrentIndex];
        if (!link) {
            return;
        }

        var overlay = lsSpEnsureLightbox();
        if (!overlay || !overlay._img) {
            return;
        }

        var imgEl = overlay._img;

        // Apply animation when changing images.
        if (lsSpAnimation === 'fade' || lsSpAnimation === 'slide') {
            // Determine direction for slide animation (1 = next, -1 = prev, 0 = unknown).
            var direction = 0;
            if (previousIndex !== -1 && previousIndex !== lsSpCurrentIndex) {
                direction = (lsSpCurrentIndex > previousIndex) ? 1 : -1;
            }

            // Clean up any previous load handler.
            if (imgEl._lsSpLoadHandler) {
                imgEl.removeEventListener('load', imgEl._lsSpLoadHandler);
            }

            imgEl._lsSpLoadHandler = function () {
                // Start from an invisible/offset state.
                imgEl.style.transition = 'none';
                imgEl.style.opacity = '0';

                if (lsSpAnimation === 'slide') {
                    var offset = (direction === 0) ? 80 : 120;
                    var sign   = (direction >= 0) ? 1 : -1;
                    imgEl.style.transform = 'translateX(' + (sign * offset) + 'px)';
                } else {
                    imgEl.style.transform = 'translateX(0)';
                }

                // Force a reflow so the browser registers the starting state.
                imgEl.style.willChange = 'opacity, transform';
                void imgEl.offsetWidth;

                // Now apply the transition and animate to the final state.
                var durationSeconds = (lsSpAnimDuration / 1000) + 's';
                imgEl.style.transition = (lsSpAnimation === 'slide')
                    ? 'opacity ' + durationSeconds + ' ease, transform ' + durationSeconds + ' ease'
                    : 'opacity ' + durationSeconds + ' ease';
                imgEl.style.opacity = '1';
                imgEl.style.transform = 'translateX(0)';
            };

            imgEl.addEventListener('load', imgEl._lsSpLoadHandler);

            // Set the new source; this will trigger the load handler for non-cached images.
            imgEl.src = link.href;

            // If the image is already cached, the load event may have fired immediately.
            // In that case, call the handler manually to ensure the animation still runs.
            if (imgEl.complete) {
                imgEl._lsSpLoadHandler();
            }
        } else {
            // Default behavior without animation.
            imgEl.style.transition = '';
            imgEl.style.opacity = '1';
            imgEl.style.transform = 'none';
            imgEl.src = link.href;
        }

        // Apply size constraints depending on lightbox theme.
        if (lsSpTheme === 'fullscreen') {
            // In fullscreen mode, let the image expand to fill the available space.
            imgEl.style.maxWidth = '100%';
            imgEl.style.maxHeight = '100%';
        } else {
            var viewportH = window.innerHeight || document.documentElement.clientHeight || 0;
            var viewportW = window.innerWidth || document.documentElement.clientWidth || 0;

            if (viewportH && viewportW) {
                // Base reserved space for caption / paddings.
                var reservedHeight = 180; // base space for caption + play button + padding

                // When Filmstrip is active, reserve additional height for the thumbnail row.
                if (lsSpTheme === 'filmstrip' && overlay && overlay._thumbs) {
                    var thumbsHeight = overlay._thumbs.offsetHeight || 80; // fallback if not rendered yet
                    reservedHeight += thumbsHeight + 16; // small gap between image and thumbs
                }

                // When Carousel is active, reserve additional height for the navigation dots.
                if (lsSpTheme === 'carousel' && overlay && overlay._dots) {
                    var dotsHeight = overlay._dots.offsetHeight || 40; // fallback if not rendered yet
                    reservedHeight += dotsHeight + 16; // small gap between image and dots
                }

                var maxH = viewportH - reservedHeight;
                var maxW = viewportW - 40;

                if (maxH < 200) { maxH = Math.max(200, viewportH * 0.6); }
                if (maxW < 200) { maxW = viewportW * 0.9; }

                imgEl.style.maxHeight = maxH + 'px';
                imgEl.style.maxWidth = maxW + 'px';
            }
        }

        var creditText = link.getAttribute('data-ls-sp-credit-text') || '';
        var creditUrl = link.getAttribute('data-ls-sp-credit-url') || '';

        if (overlay._caption) {
            if (creditText && creditUrl) {
                overlay._caption.style.display = 'block';
                overlay._caption.innerHTML =
                    '<a href="' + creditUrl + '" target="_blank" rel="noopener noreferrer" style="color:inherit;text-decoration:none;">' +
                    creditText +
                    '</a>';
            } else {
                overlay._caption.style.display = 'none';
                overlay._caption.textContent = '';
            }
        }

        overlay.style.display = 'flex';

        // Initialize/update Filmstrip thumbnails and Carousel dots if enabled.
        lsSpInitFilmstrip(overlay);
        lsSpInitCarousel(overlay);
    }

    function lsSpShowNext() {
        if (!lsSpGalleryLinks.length) {
            return;
        }
        if (lsSpCurrentIndex === -1) {
            lsSpShowIndex(0);
        } else {
            lsSpShowIndex(lsSpCurrentIndex + 1);
        }
    }

    function lsSpShowPrev() {
        if (!lsSpGalleryLinks.length) {
            return;
        }
        if (lsSpCurrentIndex === -1) {
            lsSpShowIndex(0);
        } else {
            lsSpShowIndex(lsSpCurrentIndex - 1);
        }
    }

    function lsSpToggleSlideshow() {
        var overlay = lsSpEnsureLightbox();
        if (!overlay) {
            return;
        }

        console.log('[LS Stock Portfolio] toggle slideshow, timer active =', !!lsSpSlideshowTimer);

        // If a slideshow is already running, stop it.
        if (lsSpSlideshowTimer) {
            clearInterval(lsSpSlideshowTimer);
            lsSpSlideshowTimer = null;

            // Mark play button as paused (for future visual tweaks if desired)
            if (overlay._playBtn) {
                overlay._playBtn.setAttribute('data-state', 'paused');
            }

            // Reset icon to "play" triangle
            if (overlay._playIcon) {
                var icon = overlay._playIcon;
                icon.style.width = '0';
                icon.style.height = '0';
                icon.style.borderTop = '7px solid transparent';
                icon.style.borderBottom = '7px solid transparent';
                icon.style.borderLeft = '12px solid #000000';
                icon.style.borderRight = 'none';
                icon.style.background = 'transparent';
                icon.style.boxShadow = 'none';
            }

            return;
        }

        // Ensure we have a valid starting index
        if (lsSpCurrentIndex === -1 && lsSpGalleryLinks.length) {
            lsSpShowIndex(0);
        }

        // Provide immediate visual feedback by advancing once right away
        if (lsSpGalleryLinks.length) {
            lsSpShowNext();
        }

        // Start the slideshow interval
        lsSpSlideshowTimer = setInterval(function () {
            lsSpShowNext();
        }, lsSpSlideshowInterval);

        // Mark play button as playing (for future visual tweaks if desired)
        if (overlay._playBtn) {
            overlay._playBtn.setAttribute('data-state', 'playing');
        }

        // Change icon to "pause" (two bars)
        if (overlay._playIcon) {
            var icon = overlay._playIcon;
            // Dreiecks-Borders entfernen
            icon.style.borderTop = 'none';
            icon.style.borderBottom = 'none';

            // Zwei gleich breite vertikale Balken, links und rechts
            icon.style.borderLeft = '3px solid #000000';
            icon.style.borderRight = '3px solid #000000';
            icon.style.width = '8px';
            icon.style.height = '14px';

            icon.style.background = 'transparent';
            icon.style.boxShadow = 'none';
        }
    }

    function lsSpBindLightbox() {
        // Always (re)build gallery to keep indices in sync with DOM.
        lsSpBuildGallery();

        // Attach a single delegated click listener once.
        if (lsSpLightboxClickBound) {
            return;
        }
        lsSpLightboxClickBound = true;

        document.addEventListener('click', function (e) {
            var link = null;

            if (e.target && typeof e.target.closest === 'function') {
                link = e.target.closest('.ls-sp-grid a.ls-sp-link');
            }

            if (!link) {
                return;
            }

            e.preventDefault();
            if (typeof e.stopPropagation === 'function') {
                e.stopPropagation();
            }
            if (typeof e.stopImmediatePropagation === 'function') {
                e.stopImmediatePropagation();
            }

            var idx = parseInt(link.getAttribute('data-ls-sp-index') || '0', 10);
            lsSpShowIndex(idx);
        });
    }

    function lsSpInitGrid(grid) {
        var limit = parseInt(grid.getAttribute('data-limit') || '8', 10);
        if (isNaN(limit) || limit < 1) {
            limit = 8;
        }
        var cols = parseInt(grid.getAttribute('data-cols') || '4', 10);
        if (isNaN(cols) || cols < 1) {
            cols = 4;
        }
        var gap = grid.getAttribute('data-gap') || '12px';
        var layout = grid.getAttribute('data-layout') || 'grid';
        var platform = grid.getAttribute('data-platform') || 'adobe';
        var ratio = grid.getAttribute('data-ratio') || 'auto';

        function getItems() {
            return grid.querySelectorAll('.ls-sp-item');
        }

        function calcWidthExpr() {
            var effectiveCols = cols;
            var viewportW = window.innerWidth || document.documentElement.clientWidth || 0;

            // Responsive columns are a Pro feature.
            if (lsSpIsPro && viewportW) {
                if (viewportW <= 480) {
                    // On very small screens show a single column
                    effectiveCols = 1;
                } else if (viewportW <= 768) {
                    // On small tablets/large phones show up to 2 columns
                    effectiveCols = Math.min(2, cols);
                }
                // Above 768px use the configured desktop cols value.
            }

            if (effectiveCols < 1) {
                effectiveCols = 1;
            }

            return 'calc((100% - (' + (effectiveCols - 1) + ' * ' + gap + ')) / ' + effectiveCols + ')';
        }

        function applyWidths() {
            var items = getItems();
            var widthExpr = calcWidthExpr();
            for (var i = 0; i < items.length; i++) {
                items[i].style.width = widthExpr;
            }
        }

        function resetMasonry() {
            var items = getItems();
            grid.style.position = '';
            grid.style.height = '';
            grid.style.display = 'flex';
            for (var i = 0; i < items.length; i++) {
                items[i].style.position = '';
                items[i].style.top = '';
                items[i].style.left = '';
            }
        }

        function applyMasonry() {
            if (layout !== 'masonry') {
                resetMasonry();
                return;
            }

            var items = getItems();
            var gapPx = parseInt(gap, 10);
            if (isNaN(gapPx)) {
                gapPx = 0;
            }

            grid.style.position = 'relative';
            grid.style.display = 'block';

            var colHeights = [];
            var c;
            for (c = 0; c < cols; c++) {
                colHeights[c] = 0;
            }

            for (var i = 0; i < items.length; i++) {
                var item = items[i];
                if (item.style.display === 'none') {
                    continue;
                }

                item.style.position = 'absolute';

                var targetCol = 0;
                for (c = 1; c < cols; c++) {
                    if (colHeights[c] < colHeights[targetCol]) {
                        targetCol = c;
                    }
                }

                var itemWidth = item.offsetWidth;
                var x = targetCol * (itemWidth + gapPx);
                var y = colHeights[targetCol];

                item.style.left = x + 'px';
                item.style.top = y + 'px';

                colHeights[targetCol] = y + item.offsetHeight + gapPx;
            }

            var maxHeight = 0;
            for (c = 0; c < colHeights.length; c++) {
                if (colHeights[c] > maxHeight) {
                    maxHeight = colHeights[c];
                }
            }
            grid.style.height = maxHeight + 'px';
        }

        applyWidths();
        if (layout === 'masonry') {
            window.addEventListener('load', function () {
                applyWidths();
                applyMasonry();
            });
            window.addEventListener('resize', function () {
                applyWidths();
                applyMasonry();
            });
        }

        var container = grid.closest('.ls-sp-container');
        if (container) {
            var mixBtn = container.querySelector('.ls-sp-load-more-mix');
            if (mixBtn) {
                mixBtn.addEventListener('click', function () {
                    var hidden = container.querySelector('.ls-sp-mix-hidden');
                    if (!hidden) {
                        return;
                    }

                    var perClick = limit;
                    if (!perClick || perClick < 1) {
                        perClick = 8;
                    }

                    var moved = 0;
                    while (hidden.firstElementChild && moved < perClick) {
                        var item = hidden.firstElementChild;
                        item.style.display = '';
                        grid.appendChild(item);
                        moved++;
                    }

                    applyWidths();
                    if (layout === 'masonry') {
                        applyMasonry();
                    }
                    lsSpBindLightbox();

                    if (!hidden.firstElementChild) {
                        mixBtn.textContent = (lsSpI18n.noMore || 'No more images');
                        mixBtn.disabled = true;
                        mixBtn.style.cursor = 'default';
                    }
                });
            }
        }

        var footer = grid.parentElement ? grid.parentElement.querySelector('.ls-sp-footer') : null;
        var btn = footer ? footer.querySelector('.ls-sp-more') : null;

        if (btn) {
            btn.addEventListener('click', function () {
                if (!lsSpAjaxUrl || !lsSpNonce) {
                    return;
                }

                var items = getItems();
                var offset = items.length;

                btn.disabled = true;
                var originalText = btn.textContent;
                btn.textContent = lsSpI18n.loading || 'Loading…';

                var formData;
                if (window.FormData) {
                    formData = new FormData();
                    formData.append('action', 'ls_sp_load_more');
                    formData.append('nonce', lsSpNonce);
                    formData.append('offset', offset);
                    formData.append('limit', limit);
                    formData.append('platform', platform);
                    formData.append('ratio', ratio);
                }

                function handleResponse(success, data) {
                    if (!success || !data || !data.success || !data.data) {
                        btn.disabled = false;
                        btn.textContent = lsSpI18n.error || 'Error loading images';
                        return;
                    }

                    if (data.data.html) {
                        var temp = document.createElement('div');
                        temp.innerHTML = data.data.html;
                        while (temp.firstElementChild) {
                            var child = temp.firstElementChild;
                            grid.appendChild(child);
                        }
                        applyWidths();
                        if (layout === 'masonry') {
                            applyMasonry();
                        }
                        lsSpBindLightbox();
                    }

                    if (data.data.has_more) {
                        btn.disabled = false;
                        btn.textContent = originalText || (lsSpI18n.more || 'Load more images');
                    } else {
                        btn.disabled = true;
                        btn.textContent = lsSpI18n.noMore || 'No more images';
                    }
                }

                if (window.fetch && formData) {
                    fetch(lsSpAjaxUrl, {
                        method: 'POST',
                        credentials: 'same-origin',
                        body: formData
                    })
                        .then(function (response) { return response.json(); })
                        .then(function (json) { handleResponse(true, json); })
                        .catch(function () { handleResponse(false, null); });
                } else {
                    var xhr = new XMLHttpRequest();
                    xhr.open('POST', lsSpAjaxUrl, true);
                    xhr.onreadystatechange = function () {
                        if (xhr.readyState === 4) {
                            if (xhr.status >= 200 && xhr.status < 300) {
                                var json = null;
                                try {
                                    json = JSON.parse(xhr.responseText);
                                } catch (e) {
                                    handleResponse(false, null);
                                    return;
                                }
                                handleResponse(true, json);
                            } else {
                                handleResponse(false, null);
                            }
                        }
                    };
                    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
                    var params = 'action=ls_sp_load_more' +
                        '&nonce=' + encodeURIComponent(lsSpNonce) +
                        '&offset=' + encodeURIComponent(offset) +
                        '&limit=' + encodeURIComponent(limit) +
                        '&platform=' + encodeURIComponent(platform) +
                        '&ratio=' + encodeURIComponent(ratio);
                    xhr.send(params);
                }
            });
        }
    }

    function lsSpInitAll() {
        var grids = document.querySelectorAll('.ls-sp-grid');
        if (!grids.length) {
            return;
        }

        lsSpEnsureLightbox();

        for (var i = 0; i < grids.length; i++) {
            lsSpInitGrid(grids[i]);
        }

        lsSpBindLightbox();
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', lsSpInitAll);
    } else {
        lsSpInitAll();
    }
})();