"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.backdropStackManager = void 0;
/**
 * расширяемый набор конфликтующих причин закрытия с кликом по бэкдропу модалки,
 * т.к. некоторые способы закрытия вызываются раньше, чем вызов backdropClick,
 * а при несоблюдении последовательности возникают конфликты
 */
const backdropConflictsReasons = new Set([
    'blur',
    'clickAway',
]);
class BackdropStackManager {
    constructor() {
        this.stack = [];
        /**
         * сохраняем информацию о том какой был предыдущий вызов pop,
         * нужен для предотвращения синхронного закрытия при последовательности 'blur' и 'backdropClick' в рамках одного клика
         */
        this.previousPopInfo = [null, null];
        /**
         * крайняя айдишка клика по странице
         */
        this.currentPointerId = null;
        /**
         * метод проверки на конфликт причины закрытия с предыдущим
         */
        this.checkOn = (reason) => {
            const [previousReason, previousPointerId] = this.previousPopInfo;
            return (reason === 'backdropClick' &&
                backdropConflictsReasons.has(previousReason) &&
                previousPointerId === this.currentPointerId);
        };
        /**
         * метод генерации случайной айдишки
         */
        this.generateID = () => {
            return String(Math.random());
        };
        /**
         * форс метод для удалении подписанного компонента из очереди,
         * может быть полезно при массовом анмаунте компонентов
         */
        this.remove = (id) => {
            this.stack = this.stack.filter((item) => item !== id);
        };
        /**
         * метод добавления в стек
         */
        this.push = (id) => {
            this.stack.push(id);
        };
        /**
         * метод для запроса на выход из очереди,
         * если все ок, то вернется true, что означает разрешение на выход и компонент будет вычеркнут из очереди,
         * соответственно возврат false означает запрет, и компонент остается в очереди
         */
        this.pop = (id, reason) => {
            if (this.checkOn(reason)) {
                return false;
            }
            const lastOpenedElement = this.stack[this.stack.length - 1];
            if (lastOpenedElement === id) {
                this.previousPopInfo = [reason, this.currentPointerId];
                this.stack.pop();
                return true;
            }
            return false;
        };
        globalThis?.document?.addEventListener('pointerdown', () => {
            this.currentPointerId = this.generateID();
        });
    }
}
exports.backdropStackManager = new BackdropStackManager();
