export class ResponsiveMenuManager {
    constructor(menuSelector, toggleSelector, options = {}) {
        this.isExpanded = false;
        this.isMobile = false;
        this.focusableElements = [];
        this.handleToggleClick = (event) => {
            event.preventDefault();
            this.toggleMenu();
        };
        this.handleOutsideClick = (event) => {
            if (!this.isExpanded || !this.isMobile)
                return;
            const target = event.target;
            const nav = this.menu?.closest("nav") || this.menu?.parentElement;
            if (nav && !nav.contains(target)) {
                this.close();
            }
        };
        this.handleKeydown = (event) => {
            if (!this.isExpanded)
                return;
            if (event.key === "Escape") {
                event.preventDefault();
                this.close();
                return;
            }
            if (event.key === "Tab" && this.options.trapFocus && this.isMobile) {
                this.handleTabKey(event);
            }
        };
        this.handleLinkClick = () => {
            if (this.isMobile && this.isExpanded) {
                this.close();
            }
        };
        this.handleResize = () => {
            this.checkWindowSize();
        };
        this.menu =
            typeof menuSelector === "string"
                ? document.querySelector(menuSelector)
                : menuSelector;
        this.toggle =
            typeof toggleSelector === "string"
                ? document.querySelector(toggleSelector)
                : toggleSelector;
        this.options = {
            breakpoint: options.breakpoint ?? 768,
            expandedClass: options.expandedClass ?? "nav--expanded",
            mobileClass: options.mobileClass ?? "nav--mobile",
            closeOnLinkClick: options.closeOnLinkClick ?? true,
            closeOnOutsideClick: options.closeOnOutsideClick ?? true,
            closeOnEscape: options.closeOnEscape ?? true,
            animationDuration: options.animationDuration ?? 300,
            trapFocus: options.trapFocus ?? true,
            onOpen: options.onOpen ?? (() => { }),
            onClose: options.onClose ?? (() => { }),
            linkSelector: options.linkSelector ?? "a",
        };
        if (!this.menu) {
            console.warn("[Stylescape] ResponsiveMenuManager menu element not found");
            return;
        }
        if (!this.toggle) {
            console.warn("[Stylescape] ResponsiveMenuManager toggle element not found");
            return;
        }
        this.init();
    }
    get expanded() {
        return this.isExpanded;
    }
    get mobile() {
        return this.isMobile;
    }
    open() {
        if (!this.menu || this.isExpanded)
            return;
        this.isExpanded = true;
        this.menu.hidden = false;
        this.menu.classList.add(this.options.expandedClass);
        this.toggle?.setAttribute("aria-expanded", "true");
        if (this.isMobile) {
            document.body.style.overflow = "hidden";
        }
        if (this.options.trapFocus) {
            this.updateFocusableElements();
            requestAnimationFrame(() => {
                this.focusableElements[0]?.focus();
            });
        }
        this.options.onOpen();
    }
    close() {
        if (!this.menu || !this.isExpanded)
            return;
        this.isExpanded = false;
        this.menu.classList.remove(this.options.expandedClass);
        this.toggle?.setAttribute("aria-expanded", "false");
        document.body.style.overflow = "";
        if (this.isMobile) {
            setTimeout(() => {
                if (!this.isExpanded && this.menu) {
                    this.menu.hidden = true;
                }
            }, this.options.animationDuration);
        }
        this.toggle?.focus();
        this.options.onClose();
    }
    toggleMenu() {
        if (this.isExpanded) {
            this.close();
        }
        else {
            this.open();
        }
    }
    checkWindowSize() {
        const wasMobile = this.isMobile;
        this.isMobile = window.innerWidth < this.options.breakpoint;
        const nav = this.menu?.closest("nav") || this.menu?.parentElement;
        if (this.isMobile) {
            nav?.classList.add(this.options.mobileClass);
            if (!this.isExpanded && this.menu) {
                this.menu.hidden = true;
            }
        }
        else {
            nav?.classList.remove(this.options.mobileClass);
            if (this.menu) {
                this.menu.hidden = false;
            }
            if (wasMobile && this.isExpanded) {
                this.close();
            }
        }
    }
    destroy() {
        this.toggle?.removeEventListener("click", this.handleToggleClick);
        document.removeEventListener("click", this.handleOutsideClick);
        document.removeEventListener("keydown", this.handleKeydown);
        window.removeEventListener("resize", this.handleResize);
        this.menu
            ?.querySelectorAll(this.options.linkSelector)
            .forEach((link) => {
            link.removeEventListener("click", this.handleLinkClick);
        });
        this.menu = null;
        this.toggle = null;
    }
    static initMenus() {
        const managers = [];
        document
            .querySelectorAll('[data-ss="responsive-menu"]')
            .forEach((nav) => {
            const toggle = nav.querySelector("[data-ss-menu-toggle]");
            const menu = nav.querySelector("[data-ss-menu-content]");
            if (toggle && menu) {
                const breakpoint = nav.dataset.ssMenuBreakpoint;
                managers.push(new ResponsiveMenuManager(menu, toggle, {
                    breakpoint: breakpoint
                        ? parseInt(breakpoint, 10)
                        : undefined,
                }));
            }
        });
        return managers;
    }
    init() {
        if (!this.menu || !this.toggle)
            return;
        const menuId = this.menu.id || `nav-menu-${Date.now()}`;
        this.menu.id = menuId;
        this.toggle.setAttribute("aria-controls", menuId);
        this.toggle.setAttribute("aria-expanded", "false");
        this.menu.setAttribute("role", "navigation");
        this.checkWindowSize();
        this.toggle.addEventListener("click", this.handleToggleClick);
        window.addEventListener("resize", this.handleResize);
        if (this.options.closeOnOutsideClick) {
            document.addEventListener("click", this.handleOutsideClick);
        }
        if (this.options.closeOnEscape) {
            document.addEventListener("keydown", this.handleKeydown);
        }
        if (this.options.closeOnLinkClick) {
            this.menu
                .querySelectorAll(this.options.linkSelector)
                .forEach((link) => {
                link.addEventListener("click", this.handleLinkClick);
            });
        }
    }
    updateFocusableElements() {
        if (!this.menu)
            return;
        const focusableSelectors = [
            "button:not([disabled])",
            "a[href]",
            "input:not([disabled])",
            '[tabindex]:not([tabindex="-1"])',
        ].join(",");
        this.focusableElements = Array.from(this.menu.querySelectorAll(focusableSelectors));
    }
    handleTabKey(event) {
        if (this.focusableElements.length === 0)
            return;
        const firstElement = this.focusableElements[0];
        const lastElement = this.focusableElements[this.focusableElements.length - 1];
        if (event.shiftKey) {
            if (document.activeElement === firstElement) {
                event.preventDefault();
                lastElement.focus();
            }
        }
        else {
            if (document.activeElement === lastElement) {
                event.preventDefault();
                firstElement.focus();
            }
        }
    }
}
export default ResponsiveMenuManager;
//# sourceMappingURL=ResponsiveMenuManager.js.map