import { c as classesToSelector } from '../shared/classes-to-selector.mjs';
import { a as createElement, s as makeElementsArray, b as elementIndex, w as setInnerHTML } from '../shared/utils.mjs';

const isVirtualEnabled = (swiper) => !!swiper.virtual && !!swiper.params.virtual?.enabled;
const A11y = ({ swiper, extendParams, on }) => {
    extendParams({
        a11y: {
            enabled: true,
            notificationClass: 'swiper-notification',
            prevSlideMessage: 'Previous slide',
            nextSlideMessage: 'Next slide',
            firstSlideMessage: 'This is the first slide',
            lastSlideMessage: 'This is the last slide',
            paginationBulletMessage: 'Go to slide {{index}}',
            slideLabelMessage: '{{index}} / {{slidesLength}}',
            containerMessage: null,
            containerRoleDescriptionMessage: null,
            containerRole: null,
            itemRoleDescriptionMessage: null,
            slideRole: 'group',
            id: null,
            scrollOnFocus: true,
            wrapperLiveRegion: true,
        },
    });
    swiper.a11y = {
        clicked: false,
    };
    let liveRegion = null;
    let preventFocusHandler = false;
    let focusTargetSlideEl;
    let visibilityChangedTimestamp = new Date().getTime();
    function getParams() {
        return swiper.params.a11y;
    }
    function notify(message) {
        const notification = liveRegion;
        if (!notification || !message)
            return;
        setInnerHTML(notification, message);
    }
    function getRandomNumber(size = 16) {
        const randomChar = () => Math.round(16 * Math.random()).toString(16);
        return 'x'.repeat(size).replace(/x/g, randomChar);
    }
    function makeElFocusable(el) {
        const els = makeElementsArray(el);
        els.forEach((subEl) => {
            subEl.setAttribute('tabIndex', '0');
        });
    }
    function makeElNotFocusable(el) {
        const els = makeElementsArray(el);
        els.forEach((subEl) => {
            subEl.setAttribute('tabIndex', '-1');
        });
    }
    function addElRole(el, role) {
        const els = makeElementsArray(el);
        els.forEach((subEl) => {
            subEl.setAttribute('role', role);
        });
    }
    function addElRoleDescription(el, description) {
        const els = makeElementsArray(el);
        els.forEach((subEl) => {
            subEl.setAttribute('aria-roledescription', description);
        });
    }
    function addElLabel(el, label) {
        const els = makeElementsArray(el);
        els.forEach((subEl) => {
            subEl.setAttribute('aria-label', label);
        });
    }
    function addElId(el, id) {
        const els = makeElementsArray(el);
        els.forEach((subEl) => {
            subEl.setAttribute('id', id);
        });
    }
    function addElLive(el, live) {
        const els = makeElementsArray(el);
        els.forEach((subEl) => {
            subEl.setAttribute('aria-live', live);
        });
    }
    function disableEl(el) {
        const els = makeElementsArray(el);
        els.forEach((subEl) => {
            subEl.setAttribute('aria-disabled', 'true');
        });
    }
    function enableEl(el) {
        const els = makeElementsArray(el);
        els.forEach((subEl) => {
            subEl.removeAttribute('aria-disabled');
        });
    }
    function onEnterOrSpaceKey(e) {
        if (e.keyCode !== 13 && e.keyCode !== 32)
            return;
        const params = getParams();
        const paginationParams = swiper.params.pagination;
        const targetEl = e.target;
        if (swiper.pagination &&
            swiper.pagination.el &&
            (targetEl === swiper.pagination.el || swiper.pagination.el.contains(targetEl))) {
            if (!targetEl.matches(classesToSelector(paginationParams?.bulletClass)))
                return;
        }
        if (swiper.navigation && swiper.navigation.prevEl && swiper.navigation.nextEl) {
            const prevEls = makeElementsArray(swiper.navigation.prevEl);
            const nextEls = makeElementsArray(swiper.navigation.nextEl);
            if (nextEls.includes(targetEl)) {
                if (!(swiper.isEnd && !swiper.params.loop)) {
                    swiper.slideNext();
                }
                if (swiper.isEnd) {
                    notify(params.lastSlideMessage);
                }
                else {
                    notify(params.nextSlideMessage);
                }
            }
            if (prevEls.includes(targetEl)) {
                if (!(swiper.isBeginning && !swiper.params.loop)) {
                    swiper.slidePrev();
                }
                if (swiper.isBeginning) {
                    notify(params.firstSlideMessage);
                }
                else {
                    notify(params.prevSlideMessage);
                }
            }
        }
        if (swiper.pagination && targetEl.matches(classesToSelector(paginationParams?.bulletClass))) {
            targetEl.click();
        }
    }
    function updateNavigation() {
        if (swiper.params.loop || swiper.params.rewind || !swiper.navigation)
            return;
        const { nextEl, prevEl } = swiper.navigation;
        if (prevEl) {
            if (swiper.isBeginning) {
                disableEl(prevEl);
                makeElNotFocusable(prevEl);
            }
            else {
                enableEl(prevEl);
                makeElFocusable(prevEl);
            }
        }
        if (nextEl) {
            if (swiper.isEnd) {
                disableEl(nextEl);
                makeElNotFocusable(nextEl);
            }
            else {
                enableEl(nextEl);
                makeElFocusable(nextEl);
            }
        }
    }
    function hasPagination() {
        return !!(swiper.pagination && swiper.pagination.bullets && swiper.pagination.bullets.length);
    }
    function hasClickablePagination() {
        const paginationParams = swiper.params.pagination;
        return hasPagination() && !!paginationParams?.clickable;
    }
    function updatePagination() {
        const params = getParams();
        if (!hasPagination())
            return;
        const paginationParams = swiper.params.pagination;
        swiper.pagination.bullets.forEach((bulletEl) => {
            if (paginationParams.clickable) {
                makeElFocusable(bulletEl);
                if (!paginationParams.renderBullet) {
                    addElRole(bulletEl, 'button');
                    addElLabel(bulletEl, params.paginationBulletMessage.replace(/\{\{index\}\}/, String((elementIndex(bulletEl) ?? 0) + 1)));
                }
            }
            if (bulletEl.matches(classesToSelector(paginationParams.bulletActiveClass))) {
                bulletEl.setAttribute('aria-current', 'true');
            }
            else {
                bulletEl.removeAttribute('aria-current');
            }
        });
    }
    const initNavEl = (el, _wrapperId, message) => {
        makeElFocusable(el);
        if (el.tagName !== 'BUTTON') {
            addElRole(el, 'button');
            el.addEventListener('keydown', onEnterOrSpaceKey);
        }
        addElLabel(el, message);
    };
    const handlePointerDown = (e) => {
        if (focusTargetSlideEl &&
            focusTargetSlideEl !== e.target &&
            !focusTargetSlideEl.contains(e.target)) {
            preventFocusHandler = true;
        }
        swiper.a11y.clicked = true;
    };
    const handlePointerUp = () => {
        preventFocusHandler = false;
        requestAnimationFrame(() => {
            requestAnimationFrame(() => {
                if (!swiper.destroyed) {
                    swiper.a11y.clicked = false;
                }
            });
        });
    };
    const onVisibilityChange = (_e) => {
        visibilityChangedTimestamp = new Date().getTime();
    };
    const handleFocus = (e) => {
        const params = getParams();
        if (swiper.a11y.clicked || !params.scrollOnFocus)
            return;
        if (new Date().getTime() - visibilityChangedTimestamp < 100)
            return;
        const target = e.target;
        const slideEl = target.closest(`.${swiper.params.slideClass}, swiper-slide`);
        if (!slideEl || !swiper.slides.includes(slideEl))
            return;
        focusTargetSlideEl = slideEl;
        const isVirtual = isVirtualEnabled(swiper);
        const isActive = (isVirtual
            ? parseInt(slideEl.getAttribute('data-swiper-slide-index') || '0', 10)
            : swiper.slides.indexOf(slideEl)) === swiper.activeIndex;
        const isVisible = swiper.params.watchSlidesProgress &&
            swiper.visibleSlides &&
            swiper.visibleSlides.includes(slideEl);
        if (isActive || isVisible)
            return;
        const sourceCapabilities = e.sourceCapabilities;
        if (sourceCapabilities && sourceCapabilities.firesTouchEvents)
            return;
        if (swiper.isHorizontal()) {
            swiper.el.scrollLeft = 0;
        }
        else {
            swiper.el.scrollTop = 0;
        }
        requestAnimationFrame(() => {
            if (preventFocusHandler)
                return;
            if (swiper.params.loop) {
                swiper.slideToLoop(swiper.getSlideIndexWhenGrid(parseInt(slideEl.getAttribute('data-swiper-slide-index') || '0', 10)), 0);
            }
            else if (isVirtual) {
                swiper.slideTo(swiper.getSlideIndexWhenGrid(parseInt(slideEl.getAttribute('data-swiper-slide-index') || '0', 10)), 0);
            }
            else {
                swiper.slideTo(swiper.getSlideIndexWhenGrid(swiper.slides.indexOf(slideEl)), 0);
            }
            preventFocusHandler = false;
        });
    };
    const initSlides = () => {
        const params = getParams();
        if (params.itemRoleDescriptionMessage) {
            addElRoleDescription(swiper.slides, params.itemRoleDescriptionMessage);
        }
        if (params.slideRole) {
            addElRole(swiper.slides, params.slideRole);
        }
        const slidesLength = swiper.slides.length;
        const slideLabelMessage = params.slideLabelMessage;
        if (slideLabelMessage) {
            swiper.slides.forEach((slideEl, index) => {
                const slideIndex = swiper.params.loop
                    ? parseInt(slideEl.getAttribute('data-swiper-slide-index') || '0', 10)
                    : index;
                const ariaLabelMessage = slideLabelMessage
                    .replace(/\{\{index\}\}/, String(slideIndex + 1))
                    .replace(/\{\{slidesLength\}\}/, String(slidesLength));
                addElLabel(slideEl, ariaLabelMessage);
            });
        }
    };
    const init = () => {
        const params = getParams();
        if (liveRegion)
            swiper.el.append(liveRegion);
        // Container
        const containerEl = swiper.el;
        if (params.containerRoleDescriptionMessage) {
            addElRoleDescription(containerEl, params.containerRoleDescriptionMessage);
        }
        if (params.containerMessage) {
            addElLabel(containerEl, params.containerMessage);
        }
        if (params.containerRole) {
            addElRole(containerEl, params.containerRole);
        }
        // Wrapper
        const wrapperEl = swiper.wrapperEl;
        const wrapperId = String(params.id || wrapperEl.getAttribute('id') || `swiper-wrapper-${getRandomNumber(16)}`);
        addElId(wrapperEl, wrapperId);
        if (params.wrapperLiveRegion) {
            const autoplayParams = swiper.params.autoplay;
            const live = swiper.params.autoplay && autoplayParams?.enabled ? 'off' : 'polite';
            addElLive(wrapperEl, live);
        }
        // Slide
        initSlides();
        // Navigation
        const nav = swiper.navigation
            ? swiper.navigation
            : { nextEl: undefined, prevEl: undefined };
        const nextEls = makeElementsArray(nav.nextEl);
        const prevEls = makeElementsArray(nav.prevEl);
        if (nextEls) {
            nextEls.forEach((el) => initNavEl(el, wrapperId, params.nextSlideMessage));
        }
        if (prevEls) {
            prevEls.forEach((el) => initNavEl(el, wrapperId, params.prevSlideMessage));
        }
        // Pagination
        if (hasClickablePagination()) {
            const paginationEl = makeElementsArray(swiper.pagination.el);
            paginationEl.forEach((el) => {
                el.addEventListener('keydown', onEnterOrSpaceKey);
            });
        }
        // Tab focus
        document.addEventListener('visibilitychange', onVisibilityChange);
        swiper.el.addEventListener('focus', handleFocus, true);
        swiper.el.addEventListener('pointerdown', handlePointerDown, true);
        swiper.el.addEventListener('pointerup', handlePointerUp, true);
    };
    function destroy() {
        if (liveRegion)
            liveRegion.remove();
        const nav = swiper.navigation
            ? swiper.navigation
            : { nextEl: undefined, prevEl: undefined };
        const nextEls = makeElementsArray(nav.nextEl);
        const prevEls = makeElementsArray(nav.prevEl);
        if (nextEls) {
            nextEls.forEach((el) => el.removeEventListener('keydown', onEnterOrSpaceKey));
        }
        if (prevEls) {
            prevEls.forEach((el) => el.removeEventListener('keydown', onEnterOrSpaceKey));
        }
        // Pagination
        if (hasClickablePagination()) {
            const paginationEl = makeElementsArray(swiper.pagination.el);
            paginationEl.forEach((el) => {
                el.removeEventListener('keydown', onEnterOrSpaceKey);
            });
        }
        document.removeEventListener('visibilitychange', onVisibilityChange);
        // Tab focus
        if (swiper.el && typeof swiper.el !== 'string') {
            swiper.el.removeEventListener('focus', handleFocus, true);
            swiper.el.removeEventListener('pointerdown', handlePointerDown, true);
            swiper.el.removeEventListener('pointerup', handlePointerUp, true);
        }
    }
    on('beforeInit', () => {
        liveRegion = createElement('span', getParams().notificationClass);
        liveRegion.setAttribute('aria-live', 'assertive');
        liveRegion.setAttribute('aria-atomic', 'true');
    });
    on('afterInit', () => {
        if (!getParams().enabled)
            return;
        init();
    });
    on('slidesLengthChange snapGridLengthChange slidesGridLengthChange', () => {
        if (!getParams().enabled)
            return;
        initSlides();
    });
    on('fromEdge toEdge afterInit lock unlock', () => {
        if (!getParams().enabled)
            return;
        updateNavigation();
    });
    on('paginationUpdate', () => {
        if (!getParams().enabled)
            return;
        updatePagination();
    });
    on('destroy', () => {
        if (!getParams().enabled)
            return;
        destroy();
    });
};

export { A11y as default };
