/**
 * Catalog lot-card image gallery.
 *
 * Lets buyers page through a lot's photos on the catalog card without opening
 * the lot. Enabled by Settings -> Features -> "Browse lot images in the catalog"
 * (off by default); this file is only enqueued when that option is on.
 *
 * Notes:
 *  - Fully event-delegated off document, so cards injected later by the
 *    catalogue's own AJAX paging/filtering work with no re-init.
 *  - Slides are <a> elements pointing at the lot, so clicking the photo still
 *    opens the lot exactly as before. Only the arrows/dots swallow the click.
 *  - Non-first images carry data-bp-src and are fetched on first reveal, so a
 *    page of 24 lots does not pull 150 images up front.
 *  - No jQuery dependency.
 */
(function () {
    'use strict';

    var GALLERY = '[data-bp-gallery]';
    var MANY_IMAGES = 8; // above this the dot row is hidden (see CSS)

    function slides(gallery) {
        return gallery.querySelectorAll('.bp-lot-gallery__slide');
    }

    function dots(gallery) {
        return gallery.querySelectorAll('.bp-lot-gallery__dot');
    }

    /** Resolve a slide's deferred background image the first time it is shown. */
    function hydrate(slide) {
        if (!slide) return;
        var src = slide.getAttribute('data-bp-src');
        if (!src) return;
        slide.style.backgroundImage = 'url(' + src + ')';
        slide.removeAttribute('data-bp-src');
    }

    function show(gallery, index) {
        var items = slides(gallery);
        var count = items.length;
        if (!count) return;

        // Wrap around in both directions.
        index = ((index % count) + count) % count;

        var current = parseInt(gallery.getAttribute('data-bp-index'), 10) || 0;
        if (index === current && gallery.hasAttribute('data-bp-ready')) return;

        for (var i = 0; i < count; i++) {
            var active = (i === index);
            items[i].classList.toggle('is-active', active);
            items[i].setAttribute('aria-hidden', active ? 'false' : 'true');
            items[i].setAttribute('tabindex', active ? '0' : '-1');
        }

        hydrate(items[index]);
        // Warm the neighbours so a rapid click-through does not flash empty.
        hydrate(items[(index + 1) % count]);
        hydrate(items[(index - 1 + count) % count]);

        var d = dots(gallery);
        for (var j = 0; j < d.length; j++) {
            d[j].classList.toggle('is-active', j === index);
        }

        gallery.setAttribute('data-bp-index', String(index));
        gallery.setAttribute('data-bp-ready', '1');
    }

    function step(gallery, delta) {
        var current = parseInt(gallery.getAttribute('data-bp-index'), 10) || 0;
        show(gallery, current + delta);
    }

    document.addEventListener('click', function (e) {
        var nav = e.target.closest ? e.target.closest('.bp-lot-gallery__nav') : null;
        if (nav) {
            // The arrows sit inside a card whose image links to the lot.
            e.preventDefault();
            e.stopPropagation();
            var g = nav.closest(GALLERY);
            if (g) step(g, nav.classList.contains('bp-lot-gallery__nav--next') ? 1 : -1);
            return;
        }

        var dot = e.target.closest ? e.target.closest('.bp-lot-gallery__dot') : null;
        if (dot) {
            e.preventDefault();
            e.stopPropagation();
            var gd = dot.closest(GALLERY);
            if (gd) show(gd, parseInt(dot.getAttribute('data-bp-goto'), 10) || 0);
        }
    });

    // Left/right arrow keys move through the focused card's photos.
    document.addEventListener('keydown', function (e) {
        if (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight') return;
        var active = document.activeElement;
        if (!active || !active.closest) return;
        var gallery = active.closest(GALLERY);
        if (!gallery) return;
        e.preventDefault();
        step(gallery, e.key === 'ArrowRight' ? 1 : -1);
    });

    // Horizontal swipe on touch devices.
    var touchX = null, touchY = null, touchGallery = null;
    document.addEventListener('touchstart', function (e) {
        var t = e.target;
        var gallery = (t && t.closest) ? t.closest(GALLERY) : null;
        if (!gallery || !e.touches || !e.touches.length) return;
        touchGallery = gallery;
        touchX = e.touches[0].clientX;
        touchY = e.touches[0].clientY;
    }, { passive: true });

    document.addEventListener('touchend', function (e) {
        if (touchGallery === null || touchX === null) return;
        var touch = (e.changedTouches && e.changedTouches.length) ? e.changedTouches[0] : null;
        if (touch) {
            var dx = touch.clientX - touchX;
            var dy = touch.clientY - touchY;
            // Horizontal intent only, so vertical page scrolling is unaffected.
            if (Math.abs(dx) > 40 && Math.abs(dx) > Math.abs(dy) * 1.5) {
                step(touchGallery, dx < 0 ? 1 : -1);
            }
        }
        touchGallery = null; touchX = null; touchY = null;
    }, { passive: true });

    // Flag image-heavy cards so the CSS can drop the dot row.
    function markCrowded(root) {
        var list = (root || document).querySelectorAll(GALLERY);
        for (var i = 0; i < list.length; i++) {
            if (slides(list[i]).length > MANY_IMAGES) {
                list[i].setAttribute('data-bp-many', '1');
            }
        }
    }

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

    // Catalogue paging/filtering replaces cards without a page load.
    if (window.MutationObserver) {
        var observer = new MutationObserver(function (mutations) {
            for (var i = 0; i < mutations.length; i++) {
                if (mutations[i].addedNodes && mutations[i].addedNodes.length) {
                    markCrowded();
                    return;
                }
            }
        });
        observer.observe(document.body || document.documentElement, { childList: true, subtree: true });
    }
})();
