export class AccordionManager {
    constructor(selectorOrElement, options = {}) {
        this.items = [];
        this.handleClick = (event) => {
            const header = event.currentTarget;
            const index = this.items.findIndex((item) => item.header === header);
            if (index !== -1) {
                this.toggle(index);
            }
        };
        this.handleKeydown = (event) => {
            const header = event.currentTarget;
            const index = this.items.findIndex((item) => item.header === header);
            switch (event.key) {
                case "Enter":
                case " ":
                    event.preventDefault();
                    this.toggle(index);
                    break;
                case "ArrowDown":
                    event.preventDefault();
                    this.focusHeader((index + 1) % this.items.length);
                    break;
                case "ArrowUp":
                    event.preventDefault();
                    this.focusHeader((index - 1 + this.items.length) % this.items.length);
                    break;
                case "Home":
                    event.preventDefault();
                    this.focusHeader(0);
                    break;
                case "End":
                    event.preventDefault();
                    this.focusHeader(this.items.length - 1);
                    break;
            }
        };
        this.container =
            typeof selectorOrElement === "string"
                ? document.querySelector(selectorOrElement)
                : selectorOrElement;
        this.options = {
            allowMultiple: options.allowMultiple ?? false,
            defaultOpen: options.defaultOpen ?? -1,
            animationDuration: options.animationDuration ?? 300,
            activeHeaderClass: options.activeHeaderClass ?? "accordion-header--active",
            activeContentClass: options.activeContentClass ?? "accordion-content--active",
            onOpen: options.onOpen ?? (() => { }),
            onClose: options.onClose ?? (() => { }),
            contentSelector: options.contentSelector ?? "[data-ss-accordion-content]",
        };
        if (!this.container) {
            console.warn("[Stylescape] AccordionManager container not found");
            return;
        }
        this.init();
    }
    open(index) {
        if (index < 0 || index >= this.items.length)
            return;
        if (!this.options.allowMultiple) {
            this.items.forEach((item, i) => {
                if (i !== index && item.isOpen) {
                    this.closeItem(i);
                }
            });
        }
        this.openItem(index);
    }
    close(index) {
        if (index < 0 || index >= this.items.length)
            return;
        this.closeItem(index);
    }
    toggle(index) {
        if (index < 0 || index >= this.items.length)
            return;
        if (this.items[index].isOpen) {
            this.close(index);
        }
        else {
            this.open(index);
        }
    }
    openAll() {
        this.items.forEach((_, i) => this.openItem(i));
    }
    closeAll() {
        this.items.forEach((_, i) => this.closeItem(i));
    }
    isOpen(index) {
        return this.items[index]?.isOpen ?? false;
    }
    destroy() {
        this.items.forEach((item) => {
            item.header.removeEventListener("click", this.handleClick);
            item.header.removeEventListener("keydown", this.handleKeydown);
        });
        this.items = [];
    }
    static initAccordions() {
        const managers = [];
        const accordions = document.querySelectorAll('[data-ss="accordion"]');
        accordions.forEach((el) => {
            const multiple = el.dataset.ssAccordionMultiple === "true";
            const defaultOpen = el.dataset.ssAccordionDefaultOpen;
            managers.push(new AccordionManager(el, {
                allowMultiple: multiple,
                defaultOpen: defaultOpen ? parseInt(defaultOpen, 10) : -1,
            }));
        });
        return managers;
    }
    init() {
        if (!this.container)
            return;
        const headers = this.container.querySelectorAll("[data-ss-accordion-header], .accordion-header");
        headers.forEach((header, index) => {
            const content = this.findContent(header);
            if (!content)
                return;
            const id = `accordion-content-${index}-${Date.now()}`;
            content.id = content.id || id;
            header.setAttribute("aria-expanded", "false");
            header.setAttribute("aria-controls", content.id);
            content.setAttribute("role", "region");
            content.setAttribute("aria-labelledby", header.id || `accordion-header-${index}`);
            if (!header.hasAttribute("tabindex")) {
                header.setAttribute("tabindex", "0");
            }
            content.hidden = true;
            content.style.overflow = "hidden";
            this.items.push({
                header,
                content,
                isOpen: false,
            });
            header.addEventListener("click", this.handleClick);
            header.addEventListener("keydown", this.handleKeydown);
        });
        this.openDefaults();
    }
    findContent(header) {
        const nextSibling = header.nextElementSibling;
        if (nextSibling?.matches(this.options.contentSelector)) {
            return nextSibling;
        }
        const parent = header.parentElement;
        return (parent?.querySelector(this.options.contentSelector) ??
            null);
    }
    openDefaults() {
        const defaults = this.options.defaultOpen;
        if (Array.isArray(defaults)) {
            defaults.forEach((i) => this.openItem(i));
        }
        else if (defaults >= 0) {
            this.openItem(defaults);
        }
    }
    openItem(index) {
        const item = this.items[index];
        if (!item || item.isOpen)
            return;
        item.header.setAttribute("aria-expanded", "true");
        item.header.classList.add(this.options.activeHeaderClass);
        item.content.hidden = false;
        item.content.classList.add(this.options.activeContentClass);
        const height = item.content.scrollHeight;
        item.content.style.height = "0px";
        requestAnimationFrame(() => {
            item.content.style.transition = `height ${this.options.animationDuration}ms ease`;
            item.content.style.height = `${height}px`;
            setTimeout(() => {
                item.content.style.height = "";
                item.content.style.transition = "";
            }, this.options.animationDuration);
        });
        item.isOpen = true;
        this.options.onOpen(item.header, item.content, index);
    }
    closeItem(index) {
        const item = this.items[index];
        if (!item || !item.isOpen)
            return;
        item.header.setAttribute("aria-expanded", "false");
        item.header.classList.remove(this.options.activeHeaderClass);
        item.content.classList.remove(this.options.activeContentClass);
        const height = item.content.scrollHeight;
        item.content.style.height = `${height}px`;
        requestAnimationFrame(() => {
            item.content.style.transition = `height ${this.options.animationDuration}ms ease`;
            item.content.style.height = "0px";
            setTimeout(() => {
                item.content.hidden = true;
                item.content.style.height = "";
                item.content.style.transition = "";
            }, this.options.animationDuration);
        });
        item.isOpen = false;
        this.options.onClose(item.header, item.content, index);
    }
    focusHeader(index) {
        this.items[index]?.header.focus();
    }
}
export default AccordionManager;
//# sourceMappingURL=AccordionManager.js.map