import { h } from "@stencil/core";
export class SpwDropdown {
    constructor() {
        /** Position du dropdown */
        this.direction = 'bottom';
        /** Alignement du dropdown par rapport au trigger (start/end = haut-gauche pour top/bottom, haut-bas pour left/right) */
        this.alignment = 'center';
        /** Active un padding interne */
        this.hasPadding = true;
        /** Largeur du dropdown (px) */
        this.contentWidth = 300;
        /** Hauteur max du dropdown (px) */
        this.maxHeight = 'auto';
        /** Contrôle externe du dropdown */
        this.open = false;
        this.isVisible = false;
        this.dropdownEl = null;
        this.movedContentEl = null;
        this.triggerEl = null;
        this.handleKeyDown = null;
        this.showDropdown = () => {
            var _a, _b;
            if (this.isVisible)
                return;
            const slotContent = this.host.querySelector('[slot="dropdownContent"]');
            if (!slotContent)
                return;
            this.isVisible = true;
            this.spwDropdownOpen.emit();
            this.triggerEl = (_b = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.spw-dropdown__trigger')) !== null && _b !== void 0 ? _b : null;
            this.dropdownEl = document.createElement('div');
            this.dropdownEl.className = `spw-dropdown-fixed spw-dropdown-fixed--${this.direction} spw-dropdown-fixed--${this.alignment}`;
            if (this.hasPadding)
                this.dropdownEl.classList.add('spw-dropdown-fixed--padded');
            this.dropdownEl.setAttribute('role', 'menu');
            this.dropdownEl.setAttribute('aria-modal', 'false');
            this.dropdownEl.style.width = `${this.contentWidth || 200}px`;
            this.dropdownEl.style.maxHeight = this.maxHeight !== 'auto' ? `${this.maxHeight}px` : 'none';
            this.dropdownEl.style.overflowY = this.maxHeight !== 'auto' ? 'auto' : 'visible';
            this.movedContentEl = slotContent;
            this.dropdownEl.appendChild(this.movedContentEl);
            document.body.appendChild(this.dropdownEl);
            requestAnimationFrame(() => {
                this.positionDropdown();
                this.addListeners();
                const focusable = this.getFocusableElements();
                if (focusable.length > 0) {
                    focusable[0].focus();
                }
            });
        };
        this.hideDropdown = () => {
            var _a;
            if (!this.isVisible)
                return;
            this.isVisible = false;
            this.open = false;
            this.spwDropdownClose.emit();
            if (this.dropdownEl && this.movedContentEl) {
                this.host.appendChild(this.movedContentEl);
            }
            if ((_a = this.dropdownEl) === null || _a === void 0 ? void 0 : _a.parentNode) {
                this.dropdownEl.parentNode.removeChild(this.dropdownEl);
            }
            this.dropdownEl = null;
            this.movedContentEl = null;
            this.removeListeners();
        };
    }
    async close() {
        this.open = false;
        this.hideDropdown();
    }
    onOpenChange(newVal) {
        newVal ? this.showDropdown() : this.hideDropdown();
    }
    connectedCallback() {
        this.handleClickOutside = this.handleClickOutside.bind(this);
        this.handleScrollOrResize = this.handleScrollOrResize.bind(this);
        this.handleTriggerKeyDown = this.handleTriggerKeyDown.bind(this);
        this.host.addEventListener('keydown', this.handleTriggerKeyDown);
    }
    handleTriggerKeyDown(e) {
        if ((e.key === 'Enter' || e.key === ' ') && !this.isVisible) {
            e.preventDefault();
            this.open = true;
        }
    }
    componentDidLoad() {
        if (this.open) {
            this.showDropdown();
        }
    }
    disconnectedCallback() {
        this.removeListeners();
        this.host.removeEventListener('keydown', this.handleTriggerKeyDown);
    }
    addListeners() {
        document.addEventListener('click', this.handleClickOutside, true);
        window.addEventListener('scroll', this.handleScrollOrResize, true);
        window.addEventListener('resize', this.handleScrollOrResize);
        this.handleKeyDown = (e) => {
            var _a;
            if (!this.dropdownEl)
                return;
            if (e.key === 'Escape') {
                e.preventDefault();
                this.close();
                (_a = this.triggerEl) === null || _a === void 0 ? void 0 : _a.focus();
                return;
            }
            if (e.key === 'Tab') {
                const focusable = this.getFocusableElements();
                if (focusable.length === 0)
                    return;
                const first = focusable[0];
                const last = focusable[focusable.length - 1];
                if (e.shiftKey) {
                    if (document.activeElement === first) {
                        e.preventDefault();
                        last.focus();
                    }
                }
                else {
                    if (document.activeElement === last) {
                        e.preventDefault();
                        first.focus();
                    }
                }
                return;
            }
            if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
                e.preventDefault();
                const focusable = this.getFocusableElements();
                if (focusable.length === 0)
                    return;
                const currentIndex = focusable.indexOf(document.activeElement);
                if (e.key === 'ArrowDown') {
                    const next = currentIndex < focusable.length - 1 ? currentIndex + 1 : 0;
                    focusable[next].focus();
                }
                else {
                    const prev = currentIndex > 0 ? currentIndex - 1 : focusable.length - 1;
                    focusable[prev].focus();
                }
            }
        };
        document.addEventListener('keydown', this.handleKeyDown, true);
    }
    removeListeners() {
        document.removeEventListener('click', this.handleClickOutside, true);
        window.removeEventListener('scroll', this.handleScrollOrResize, true);
        window.removeEventListener('resize', this.handleScrollOrResize);
        if (this.handleKeyDown) {
            document.removeEventListener('keydown', this.handleKeyDown, true);
            this.handleKeyDown = null;
        }
    }
    getFocusableElements() {
        if (!this.dropdownEl)
            return [];
        return Array.from(this.dropdownEl.querySelectorAll('a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"]), input:not([disabled]), select:not([disabled]), textarea:not([disabled])')).filter(el => !el.closest('[aria-disabled="true"]'));
    }
    handleClickOutside(event) {
        var _a;
        if (!this.host.contains(event.target) && !((_a = this.dropdownEl) === null || _a === void 0 ? void 0 : _a.contains(event.target))) {
            this.close();
        }
    }
    handleScrollOrResize() {
        if (this.isVisible) {
            this.positionDropdown();
        }
    }
    positionDropdown() {
        var _a;
        if (!this.dropdownEl)
            return;
        const trigger = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.spw-dropdown__trigger');
        if (!trigger)
            return;
        const rect = trigger.getBoundingClientRect();
        const dropdown = this.dropdownEl;
        dropdown.style.visibility = 'hidden';
        dropdown.style.position = 'fixed';
        dropdown.style.display = 'flex';
        const dropdownRect = dropdown.getBoundingClientRect();
        let top = 0;
        let left = 0;
        const alignedLeft = (() => {
            switch (this.alignment) {
                case 'start': return rect.left;
                case 'end': return rect.right - dropdownRect.width;
                case 'center':
                default: return rect.left + (rect.width - dropdownRect.width) / 2;
            }
        })();
        const alignedTop = (() => {
            switch (this.alignment) {
                case 'start': return rect.top;
                case 'end': return rect.bottom - dropdownRect.height;
                case 'center':
                default: return rect.top + (rect.height - dropdownRect.height) / 2;
            }
        })();
        switch (this.direction) {
            case 'top':
                top = rect.top - dropdownRect.height - 8;
                left = alignedLeft;
                break;
            case 'bottom':
                top = rect.bottom + 8;
                left = alignedLeft;
                break;
            case 'left':
                top = alignedTop;
                left = rect.left - dropdownRect.width - 8;
                break;
            case 'right':
            default:
                top = alignedTop;
                left = rect.right + 8;
                break;
        }
        dropdown.style.top = `${top}px`;
        dropdown.style.left = `${left}px`;
        dropdown.style.zIndex = '9999';
        dropdown.style.visibility = 'visible';
    }
    render() {
        return (h("div", { key: '9436b4657389ba587830dcc8f7dc9f13aa33ef0a', class: "spw-dropdown__trigger", onClick: () => (this.open = !this.open), "aria-expanded": this.open ? 'true' : 'false', "aria-haspopup": "menu" }, h("slot", { key: '3abcf24a43d046fde173ffe2ac73d376cf78ec6e' })));
    }
    static get is() { return "spw-dropdown"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["spw-dropdown.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["spw-dropdown.css"]
        };
    }
    static get properties() {
        return {
            "direction": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'top' | 'bottom' | 'left' | 'right'",
                    "resolved": "\"bottom\" | \"left\" | \"right\" | \"top\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Position du dropdown"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "direction",
                "defaultValue": "'bottom'"
            },
            "alignment": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'start' | 'center' | 'end'",
                    "resolved": "\"center\" | \"end\" | \"start\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Alignement du dropdown par rapport au trigger (start/end = haut-gauche pour top/bottom, haut-bas pour left/right)"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "alignment",
                "defaultValue": "'center'"
            },
            "hasPadding": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Active un padding interne"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "has-padding",
                "defaultValue": "true"
            },
            "contentWidth": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Largeur du dropdown (px)"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "content-width",
                "defaultValue": "300"
            },
            "maxHeight": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Hauteur max du dropdown (px)"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "max-height",
                "defaultValue": "'auto'"
            },
            "open": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Contr\u00F4le externe du dropdown"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "open",
                "defaultValue": "false"
            }
        };
    }
    static get states() {
        return {
            "isVisible": {}
        };
    }
    static get events() {
        return [{
                "method": "spwDropdownOpen",
                "name": "spwDropdownOpen",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "\u00C9v\u00E9nement \u00E9mis quand le dropdown s'ouvre"
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "spwDropdownClose",
                "name": "spwDropdownClose",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "\u00C9v\u00E9nement \u00E9mis quand le dropdown se ferme"
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }];
    }
    static get methods() {
        return {
            "close": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": []
                }
            }
        };
    }
    static get elementRef() { return "host"; }
    static get watchers() {
        return [{
                "propName": "open",
                "methodName": "onOpenChange"
            }];
    }
}
