import { Host, h } from "@stencil/core";
import { queryShadowRoot, isHidden, isFocusable } from "../../utils/focus-trap";
import { animationTo, KEYFRAMES } from "../../utils/animation";
export class SpwModal {
    constructor() {
        /** Indique si la modal est ouverte ou fermée, mutable et reflétée dans le DOM */
        this.opened = false;
        this.showModal = this.opened || false;
        /** Titre de la modal */
        this.caption = 'Titre de la modal';
        /** Texte du bouton de fermeture */
        this.closeButtonText = 'Fermer';
        /** Indique si la fermeture de la modal est possible en cliquant sur l'overlay */
        this.closeOnOverlayClick = true;
        /** Rend les boutons en bas de la modal "collants" (toujours visibles) si vrai */
        this.stickyButtons = false;
        /** Définit la taille de la modal : 'small', 'medium', 'large' ou 'fluid' */
        this.size = 'small';
        /** Icône d'alerte à afficher dans la modal (référence font awesome) */
        this.alertIcon = '';
        this.slotButtonsPresent = false;
        this.isCloseButtonSticky = false;
        /** Indique si le bouton de fermeture est visible */
        this.showCloseButton = true;
        this.focusableElements = [];
        this.handleClick = (event) => {
            const path = event.composedPath();
            const trigger = path.find(el => { var _a; return el instanceof HTMLElement && ((_a = el.hasAttribute) === null || _a === void 0 ? void 0 : _a.call(el, 'data-modal-trigger')); });
            if (trigger) {
                const modalId = trigger.getAttribute('data-modal-trigger');
                if (modalId === this.hostElement.id) {
                    this.opened = true;
                }
            }
        };
        this.handleClose = (event) => {
            const path = event.composedPath();
            const trigger = path.find(el => { var _a; return el instanceof HTMLElement && ((_a = el.hasAttribute) === null || _a === void 0 ? void 0 : _a.call(el, 'data-modal-close')); });
            if (trigger) {
                const modalId = trigger.getAttribute('data-modal-close');
                if (modalId === this.hostElement.id) {
                    this.opened = false;
                }
            }
        };
        // private getLastFocusableElement(): HTMLElement | null {
        //   return this.focusableElements[this.focusableElements.length - 1];
        // }
        // private handleTopFocus = () => {
        //   this.attemptFocus(this.getLastFocusableElement());
        // };
        this.handleBottomFocus = () => {
            this.attemptFocus(this.getFirstFocusableElement());
        };
        this.handleKeypress = (event) => {
            if (this.showModal && event.key === 'Escape') {
                this.doBeforeClose('ESCAPE_KEY');
            }
        };
        this.handleContentScroll = () => {
            if (this.modalContent) {
                this.isCloseButtonSticky = this.modalContent.scrollTop >= 60;
            }
        };
    }
    /**
     * Méthode publique pour fermer la modal programmatiquement
     * @returns Promise qui se résout quand la modal est fermée
     */
    async closeModal() {
        this.doBeforeClose('PROGRAMMATIC');
    }
    /**
     * Méthode publique pour ouvrir la modal programmatiquement
     * @returns Promise qui se résout quand la modal est ouverte
     */
    async openModal() {
        this.opened = true;
    }
    componentDidLoad() {
        this.focusableElements = queryShadowRoot(this.hostElement.shadowRoot, el => isHidden(el) || el.matches('[data-focus-trap-edge]'), isFocusable);
        window.addEventListener('click', this.handleClick, { capture: true });
        window.addEventListener('click', this.handleClose, { capture: true });
        window.addEventListener('keydown', this.handleKeypress);
    }
    disconnectedCallback() {
        window.removeEventListener('click', this.handleClick);
        window.removeEventListener('click', this.handleClose);
        window.removeEventListener('keydown', this.handleKeypress);
    }
    getFirstFocusableElement() {
        return this.focusableElements[0];
    }
    attemptFocus(element) {
        if (element == null) {
            setTimeout(() => {
                this.closeButton.focus();
            });
            return;
        }
        setTimeout(() => {
            element.focus();
        }, 0);
    }
    open() {
        this.showModal = true;
        this.isCloseButtonSticky = false;
        requestAnimationFrame(() => {
            if (this.modalContent) {
                this.modalContent.scrollTop = 0;
            }
        });
        try {
            const anim = animationTo(this.modalContainer, KEYFRAMES.fadeIn, {
                duration: 200,
            });
            anim.addEventListener('finish', () => {
                setTimeout(() => {
                    // this.getLastFocusableElement()?.focus();
                    // this.getLastFocusableElement()?.blur();
                }, 0);
                this.spwModalOpen.emit();
            });
        }
        catch (err) {
            this.spwModalOpen.emit();
        }
    }
    close() {
        this.stopAllVideos();
        try {
            const anim = animationTo(this.modalContainer, KEYFRAMES.fadeOut, {
                duration: 200,
            });
            anim.addEventListener('finish', () => {
                this.showModal = false;
                this.spwModalClose.emit();
            });
        }
        catch (err) {
            this.showModal = false;
            this.spwModalClose.emit();
        }
    }
    stopAllVideos() {
        const iframes = this.hostElement.querySelectorAll('iframe');
        iframes.forEach(iframe => {
            iframe.src = iframe.src;
        });
    }
    doBeforeClose(trigger) {
        const triggers = [];
        triggers.push(trigger);
        const prevented = triggers.some(event => event.defaultPrevented);
        if (!prevented) {
            this.opened = false;
        }
    }
    openedChanged(newValue) {
        newValue === true ? this.open() : this.close();
    }
    handleOverlayClick() {
        if (this.closeOnOverlayClick) {
            this.doBeforeClose('BACKDROP');
        }
    }
    get elementClass() {
        return {
            'spw-modal': true,
            'spw-modal--opened': this.showModal,
            'spw-modal--sticky-buttons': this.stickyButtons,
        };
    }
    render() {
        return (h(Host, { key: '4eb87501a9a4cc098250700f58c027e3f3fc13c6' }, h("div", { key: '100bc778f67fca4ebc8ca8e1933033a362f94c24', ref: el => (this.modalContainer = el), class: this.elementClass }, h("div", { key: '56918adc60d5b97ffd43e66323a4fc28f72c6297', class: "spw-modal__overlay", onClick: () => this.handleOverlayClick() }), h("div", { key: '65612030c666acfaa5bafccff02b265e2df49408', class: `spw-modal__content-container spw-modal__content-container--${this.size}`, role: "dialog", "aria-modal": "true", "aria-label": this.caption }, h("div", { key: '51ce6d5e32a972e6c7c7ff95844c6aab0793a979', class: "spw-modal__content", ref: el => (this.modalContent = el), onScroll: this.handleContentScroll }, h("div", { key: '92deb26800d917a018012ae8dab17491fdfade57', class: "spw-modal__header" }, h("div", { key: 'a96de8538e42a2ef89c2669459a4921bb818ad03', class: "spw-modal__title-container" }, this.alertIcon && h("spw-icon", { key: '4328a281475bb9fb969234010872d83ad7c7db72', class: "spw-modal__alert-icon", icon: this.alertIcon }), h("h2", { key: '7c16016aaaced617feb2cbdddb225c0de07c9294', class: "spw-modal__caption" }, this.caption)), this.showCloseButton && (h("div", { key: '3cfd868ed08d69d6eacbc2e2908da0f1ae68236e', class: {
                'spw-modal__close-button': true,
                'spw-modal__close-button--sticky': this.isCloseButtonSticky,
            }, ref: el => (this.closeButton = el), onClick: () => this.doBeforeClose('CLOSE_BUTTON') }, h("spw-link", { key: '36577f9858f3eaa116b41af3e2654b6a0d803fe5', "icon-position": "right", icon: "fa-xmark" }, this.closeButtonText)))), h("div", { key: 'f1fae039840a285805410fee667a4e5c53d441ea', class: "spw-modal__body" }, h("slot", { key: '199cc1dfa3507fee34d5a86f90c35948ad656549', name: "content" })), h("div", { key: '83bfe6dfccb359f373c3e0b7080893a716eb6812', class: { 'spw-modal__buttons': true, 'spw-modal__footer--buttons-present': this.slotButtonsPresent } }, h("slot", { key: '7bc4e5745527068f0cc6eb2bfedc7440e99a0199', name: "buttons", onSlotchange: (e) => {
                const slot = e.target;
                this.slotButtonsPresent = slot.assignedNodes({ flatten: true }).length > 0;
            } })))), h("div", { key: '57d4de3c3d2d5769b14388d16c30471091007af0', "data-focus-trap-edge": true, onFocus: this.handleBottomFocus, tabindex: "0" }))));
    }
    static get is() { return "spw-modal"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["spw-modal.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["spw-modal.css"]
        };
    }
    static get properties() {
        return {
            "opened": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Indique si la modal est ouverte ou ferm\u00E9e, mutable et refl\u00E9t\u00E9e dans le DOM"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "opened",
                "defaultValue": "false"
            },
            "caption": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Titre de la modal"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "caption",
                "defaultValue": "'Titre de la modal'"
            },
            "closeButtonText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Texte du bouton de fermeture"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "close-button-text",
                "defaultValue": "'Fermer'"
            },
            "closeOnOverlayClick": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Indique si la fermeture de la modal est possible en cliquant sur l'overlay"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "close-on-overlay-click",
                "defaultValue": "true"
            },
            "stickyButtons": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Rend les boutons en bas de la modal \"collants\" (toujours visibles) si vrai"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "sticky-buttons",
                "defaultValue": "false"
            },
            "size": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'small' | 'medium' | 'large' | 'fluid'",
                    "resolved": "\"fluid\" | \"large\" | \"medium\" | \"small\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "D\u00E9finit la taille de la modal : 'small', 'medium', 'large' ou 'fluid'"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "size",
                "defaultValue": "'small'"
            },
            "alertIcon": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Ic\u00F4ne d'alerte \u00E0 afficher dans la modal (r\u00E9f\u00E9rence font awesome)"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "alert-icon",
                "defaultValue": "''"
            },
            "showCloseButton": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Indique si le bouton de fermeture est visible"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "show-close-button",
                "defaultValue": "true"
            }
        };
    }
    static get states() {
        return {
            "showModal": {},
            "slotButtonsPresent": {},
            "isCloseButtonSticky": {}
        };
    }
    static get events() {
        return [{
                "method": "spwModalOpen",
                "name": "spwModalOpen",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "\u00C9v\u00E9nement d\u00E9clench\u00E9 lors de l'ouverture de la modal"
                },
                "complexType": {
                    "original": "any",
                    "resolved": "any",
                    "references": {}
                }
            }, {
                "method": "spwModalClose",
                "name": "spwModalClose",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "\u00C9v\u00E9nement d\u00E9clench\u00E9 lors de la fermeture de la modal"
                },
                "complexType": {
                    "original": "any",
                    "resolved": "any",
                    "references": {}
                }
            }];
    }
    static get methods() {
        return {
            "closeModal": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "M\u00E9thode publique pour fermer la modal programmatiquement",
                    "tags": [{
                            "name": "returns",
                            "text": "Promise qui se r\u00E9sout quand la modal est ferm\u00E9e"
                        }]
                }
            },
            "openModal": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "M\u00E9thode publique pour ouvrir la modal programmatiquement",
                    "tags": [{
                            "name": "returns",
                            "text": "Promise qui se r\u00E9sout quand la modal est ouverte"
                        }]
                }
            }
        };
    }
    static get elementRef() { return "hostElement"; }
    static get watchers() {
        return [{
                "propName": "opened",
                "methodName": "openedChanged"
            }];
    }
}
