/**
 * Elementor frontend handler for the Gallery Listing widget.
 *
 * Provides category filtering (with a fade transition) and a dependency-free,
 * accessible lightbox: prev / next navigation, keyboard support (Esc, ← →),
 * focus trapping on the controls and backdrop / button close. One controller per
 * instance with editor-safe teardown.
 *
 * @package captain-widgets-kit
 * @since   1.5.0
 */

(function ($) {
    'use strict';

    /**
     * Per-instance handler — called by Elementor for every widget instance.
     *
     * @param {jQuery} $scope - The widget wrapper element.
     */
    var CaptwikiGalleryHandler = function ($scope) {

        var root = $scope[0].querySelector('.captwiki-gallery');
        if (!root) return;

        if (root._cwkTeardown) {
            root._cwkTeardown();
        }

        var grid = root.querySelector('.captwiki-gallery__grid');
        if (!grid) return;

        var items = Array.prototype.slice.call(grid.querySelectorAll('.captwiki-gallery__item'));
        var filters = Array.prototype.slice.call(root.querySelectorAll('.captwiki-gallery__filter'));
        var lightboxLinks = Array.prototype.slice.call(root.querySelectorAll('.captwiki-gallery__link[data-lightbox="true"]'));

        var handlers = [];
        var lightbox = null;
        var lastFocused = null;
        var currentIndex = 0;

        /**
         * Add an event listener and remember it for later teardown.
         *
         * @param {Element|Window} el - Target.
         * @param {string} type       - Event name.
         * @param {Function} fn       - Listener.
         */
        function on(el, type, fn) {
            if (!el) return;
            el.addEventListener(type, fn);
            handlers.push(function () { el.removeEventListener(type, fn); });
        }

        /* ── Filtering ─────────────────────────────────────── */

        /**
         * Show only the items matching a category slug.
         *
         * @param {string} filter - Category slug, or '*' for all.
         */
        function applyFilter(filter) {
            items.forEach(function (item) {
                var match = filter === '*' || item.getAttribute('data-category') === filter;
                if (match) {
                    item.hidden = false;
                    item.classList.remove('is-hidden');
                } else {
                    item.classList.add('is-hidden');
                    item.hidden = true;
                }
            });
        }

        filters.forEach(function (btn) {
            on(btn, 'click', function () {
                filters.forEach(function (b) {
                    b.classList.remove('is-active');
                    b.setAttribute('aria-selected', 'false');
                });
                btn.classList.add('is-active');
                btn.setAttribute('aria-selected', 'true');
                applyFilter(btn.getAttribute('data-filter') || '*');
            });
        });

        /* ── Lightbox ──────────────────────────────────────── */

        /**
         * Build the lightbox DOM once and wire its controls.
         *
         * @return {Object} References to the lightbox parts.
         */
        function buildLightbox() {
            var overlay = document.createElement('div');
            overlay.className = 'captwiki-gallery-lightbox';
            overlay.setAttribute('role', 'dialog');
            overlay.setAttribute('aria-modal', 'true');
            overlay.setAttribute('aria-label', 'Image lightbox');
            overlay.hidden = true;

            overlay.innerHTML =
                '<div class="captwiki-gallery-lightbox__backdrop" data-close="true"></div>' +
                '<div class="captwiki-gallery-lightbox__stage">' +
                    '<button type="button" class="captwiki-gallery-lightbox__btn captwiki-gallery-lightbox__prev" aria-label="Previous">' +
                        '<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 18l-6-6 6-6"></path></svg>' +
                    '</button>' +
                    '<figure class="captwiki-gallery-lightbox__figure">' +
                        '<img class="captwiki-gallery-lightbox__img" src="" alt="">' +
                        '<figcaption class="captwiki-gallery-lightbox__caption"></figcaption>' +
                    '</figure>' +
                    '<button type="button" class="captwiki-gallery-lightbox__btn captwiki-gallery-lightbox__next" aria-label="Next">' +
                        '<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18l6-6-6-6"></path></svg>' +
                    '</button>' +
                    '<button type="button" class="captwiki-gallery-lightbox__btn captwiki-gallery-lightbox__close" aria-label="Close">' +
                        '<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6L6 18M6 6l12 12"></path></svg>' +
                    '</button>' +
                    '<span class="captwiki-gallery-lightbox__counter"></span>' +
                '</div>';

            document.body.appendChild(overlay);

            return {
                overlay: overlay,
                img: overlay.querySelector('.captwiki-gallery-lightbox__img'),
                caption: overlay.querySelector('.captwiki-gallery-lightbox__caption'),
                counter: overlay.querySelector('.captwiki-gallery-lightbox__counter'),
                prev: overlay.querySelector('.captwiki-gallery-lightbox__prev'),
                next: overlay.querySelector('.captwiki-gallery-lightbox__next'),
                close: overlay.querySelector('.captwiki-gallery-lightbox__close')
            };
        }

        /**
         * Only the currently visible lightbox links are navigable.
         *
         * @return {Array} Visible link elements.
         */
        function visibleLinks() {
            return lightboxLinks.filter(function (link) {
                var item = link.closest('.captwiki-gallery__item');
                return item && !item.hidden;
            });
        }

        /**
         * Load an image into the open lightbox.
         *
         * @param {Array}  list  - Navigable links.
         * @param {number} index - Target index.
         */
        function showImage(list, index) {
            if (!list.length) return;
            currentIndex = (index + list.length) % list.length;

            var link = list[currentIndex];
            var title = link.getAttribute('data-title') || '';
            var caption = link.getAttribute('data-caption') || '';

            lightbox.img.setAttribute('src', link.getAttribute('href'));
            lightbox.img.setAttribute('alt', title);

            var captionHtml = '';
            if (title) captionHtml += '<strong>' + title + '</strong>';
            if (caption) captionHtml += '<span>' + caption + '</span>';
            lightbox.caption.innerHTML = captionHtml;
            lightbox.caption.hidden = captionHtml === '';

            lightbox.counter.textContent = (currentIndex + 1) + ' / ' + list.length;

            var single = list.length < 2;
            lightbox.prev.hidden = single;
            lightbox.next.hidden = single;
        }

        /**
         * Open the lightbox at a given link.
         *
         * @param {Element} link - The clicked gallery link.
         */
        function openLightbox(link) {
            if (!lightbox) lightbox = buildLightbox();
            bindLightboxEvents();

            lastFocused = document.activeElement;
            var list = visibleLinks();
            var index = list.indexOf(link);

            showImage(list, index < 0 ? 0 : index);

            lightbox.overlay.hidden = false;
            document.body.classList.add('captwiki-gallery-lightbox-open');
            lightbox.close.focus();
        }

        /**
         * Close the lightbox and restore focus.
         */
        function closeLightbox() {
            if (!lightbox) return;
            lightbox.overlay.hidden = true;
            document.body.classList.remove('captwiki-gallery-lightbox-open');
            if (lastFocused && typeof lastFocused.focus === 'function') {
                lastFocused.focus();
            }
        }

        var lightboxBound = false;

        /**
         * Wire the lightbox control events once.
         */
        function bindLightboxEvents() {
            if (lightboxBound) return;
            lightboxBound = true;

            on(lightbox.next, 'click', function () { showImage(visibleLinks(), currentIndex + 1); });
            on(lightbox.prev, 'click', function () { showImage(visibleLinks(), currentIndex - 1); });
            on(lightbox.close, 'click', closeLightbox);

            on(lightbox.overlay, 'click', function (e) {
                if (e.target.getAttribute('data-close') === 'true') {
                    closeLightbox();
                }
            });

            on(document, 'keydown', function (e) {
                if (lightbox.overlay.hidden) return;
                if (e.key === 'Escape') {
                    closeLightbox();
                } else if (e.key === 'ArrowRight') {
                    showImage(visibleLinks(), currentIndex + 1);
                } else if (e.key === 'ArrowLeft') {
                    showImage(visibleLinks(), currentIndex - 1);
                }
            });
        }

        lightboxLinks.forEach(function (link) {
            on(link, 'click', function (e) {
                e.preventDefault();
                openLightbox(link);
            });
        });

        /* ── Teardown ──────────────────────────────────────── */
        root._cwkTeardown = function () {
            handlers.forEach(function (off) { off(); });
            handlers = [];
            if (lightbox && lightbox.overlay && lightbox.overlay.parentNode) {
                lightbox.overlay.parentNode.removeChild(lightbox.overlay);
            }
            document.body.classList.remove('captwiki-gallery-lightbox-open');
            lightbox = null;
            root._cwkTeardown = null;
        };
    };

    /* ── Register with Elementor frontend ───────────────────── */
    $(window).on('elementor/frontend/init', function () {
        elementorFrontend.hooks.addAction(
            'frontend/element_ready/captwiki-gallery-listing.default',
            CaptwikiGalleryHandler
        );
    });

})(jQuery);
