import { h, Host } from "@stencil/core";
import { DialogHeadingLevel } from "./dialog-heading-level.enum";
import { DialogVariation } from "./dialog-variation.enum";
import { DialogSize } from "./dialog-size.enum";
import { randomIdGenerator } from "../../../global/utils/randomIdGenerator";
import { ButtonSize, ButtonVariation } from "../../../enums";
/**
 * @slot default - Kan innehålla vad som helst
 * @slot over-heading - Innehåll som hamnar över den inbyggda rubriken
 * @enums DialogHeadingLevel - dialog-heading-level.enum.ts
 * @enums DialogSize - dialog-size.enum.ts
 * @enums DialogVariation - dialog-variation.enum.ts (beta)
 * @swedishName Modal
 */
export class Dialog {
    constructor() {
        this._focusableElementsSelectors = 'a, input, select, textarea, button, button:not(hidden), iframe, object, [tabindex="0"]';
        this.focusableElements = [];
        this.afId = randomIdGenerator('digi-dialog');
        this.afVariation = DialogVariation.PRIMARY;
        this.afSize = DialogSize.MEDIUM;
        this.afShowDialog = undefined;
        this.afCloseButtonText = 'Stäng';
        this.afHeadingLevel = DialogHeadingLevel.H2;
        this.afHeading = undefined;
        this.afPrimaryButtonText = undefined;
        this.afSecondaryButtonText = undefined;
        this.afFallbackElementSelector = undefined;
    }
    primaryClickHandler(e) {
        this.afPrimaryButtonClick.emit(e);
    }
    secondaryClickHandler(e) {
        this.afSecondaryButtonClick.emit(e);
    }
    escHandler(e) {
        if (this._closeButton) {
            this.closeDialog(e);
        }
    }
    shiftHandler(e) {
        let el;
        if (document.activeElement.tagName === 'DIGI-DIALOG') {
            el = document.activeElement.shadowRoot.activeElement;
        }
        else {
            el = document.activeElement;
        }
        if (this.shouldUseFocusTrap) {
            if (el === this._dialogHeading && !!this.closeButtonEl) {
                e.detail.preventDefault();
                this.closeButtonEl.focus();
            }
            else if (el === this.firstFocusableEl && !!this.closeButtonEl) {
                e.detail.preventDefault();
                this.closeButtonEl.focus();
            }
            else if (el === this._dialogHeading && !this.closeButtonEl) {
                e.detail.preventDefault();
                this.lastFocusableEl.focus();
            }
            else if (el === this.firstFocusableEl && !this.closeButtonEl) {
                e.detail.preventDefault();
                this.lastFocusableEl.focus();
            }
            else if (el === this.closeButtonEl) {
                e.detail.preventDefault();
                this.lastFocusableEl.focus();
            }
        }
        else {
            e.detail.preventDefault();
        }
    }
    tabHandler(e) {
        let el;
        if (document.activeElement.tagName === 'DIGI-DIALOG') {
            el = document.activeElement.shadowRoot.activeElement;
        }
        else {
            el = document.activeElement;
        }
        if (this.shouldUseFocusTrap) {
            if (el === this.lastFocusableEl && !!this.closeButtonEl) {
                e.detail.preventDefault();
                this.closeButtonEl.focus();
            }
            else if (el === this.closeButtonEl || el === this.lastFocusableEl) {
                e.detail.preventDefault();
                this.firstFocusableEl.focus();
            }
        }
        else {
            e.detail.preventDefault();
        }
    }
    onActive() {
        document.body.style.overflow = 'hidden';
        if (!this.afCloseButtonText) {
            this._wrapper.style.paddingTop = '25px';
        }
        if (this._dialogHeading) {
            this._dialogHeading.style.marginTop = '0';
        }
        this.onResize();
        setTimeout(() => {
            this.setFallback();
            this.getFocusableItems();
            this.setFocus();
        }, 50);
    }
    buttonWidthMaxContent() {
        if (this._primaryButton) {
            this._primaryButton.style.width = 'max-content';
            this._primaryButton.querySelector('button').style.width = 'max-content';
        }
        if (this._secondaryButton) {
            this._secondaryButton.style.width = 'max-content';
            this._secondaryButton.querySelector('button').style.width = 'max-content';
        }
    }
    buttonWidth100Percent() {
        if (this._primaryButton) {
            this._primaryButton.style.width = '100%';
            this._primaryButton.querySelector('button').style.width = '100%';
        }
        if (this._secondaryButton) {
            this._secondaryButton.style.width = '100%';
            this._secondaryButton.querySelector('button').style.width = '100%';
        }
    }
    onResize() {
        this.buttonContainerObserver = new ResizeObserver(() => {
            if (this._buttonContainer.clientWidth <= 313) {
                this.buttonWidth100Percent();
            }
            else {
                this.buttonWidthMaxContent();
            }
        });
        this.buttonContainerObserver.observe(this._buttonContainer);
    }
    onInactive() {
        const el = this.fallbackElement;
        if (el) {
            el.focus();
        }
        this.buttonContainerObserver.disconnect();
        document.body.style.overflow = '';
    }
    closeDialog(e) {
        this.afShowDialog = false;
        this.afOnClose.emit(e);
    }
    setFallback() {
        if (!!this.afFallbackElementSelector &&
            !!document.querySelector(this.afFallbackElementSelector)) {
            this.fallbackElement = document.querySelector(this.afFallbackElementSelector);
            if (this.fallbackElement instanceof HTMLHeadingElement) {
                this.fallbackElement.setAttribute('tabindex', '-1');
            }
        }
        else {
            this.fallbackElement = document.activeElement;
        }
    }
    setFocus() {
        if (this.afShowDialog) {
            let el;
            if (this.afHeading) {
                el = this._dialogHeading;
                this._dialogHeading.style.outline = 'none';
            }
            else if (this.firstFocusableEl) {
                el = this.firstFocusableEl;
                if (!el.getAttribute('tabindex')) {
                    el.setAttribute('tabindex', '0');
                }
            }
            else if (this.closeButtonEl) {
                el = this.closeButtonEl;
            }
            else {
                el = this._wrapper;
                el.setAttribute('tabindex', '0');
            }
            if (el) {
                el.focus();
            }
        }
    }
    getFocusableItems() {
        let allElements;
        const slotElements = this._host.querySelectorAll(this._focusableElementsSelectors);
        const defaultElements = this._wrapper.querySelectorAll(this._focusableElementsSelectors);
        if (this._closeButton) {
            this.closeButtonEl = this._closeButton.children[0];
            const defaultElementsWithoutCloseButton = Array.prototype.slice.call(defaultElements);
            defaultElementsWithoutCloseButton.shift();
            allElements = Array.from(slotElements).concat(Array.from(defaultElementsWithoutCloseButton));
        }
        else {
            allElements = Array.from(slotElements).concat(Array.from(defaultElements));
        }
        this.focusableElements = allElements;
        if (this.focusableElements.length > 0) {
            this.firstFocusableEl = this.focusableElements[0];
            this.lastFocusableEl = this.focusableElements[this.focusableElements.length - 1];
        }
    }
    componentDidLoad() {
        if (this.afShowDialog) {
            this.onActive();
        }
    }
    componentDidUpdate() {
        if (this.afShowDialog) {
            this.onActive();
        }
        else if (!this.afShowDialog && this.fallbackElement) {
            this.onInactive();
        }
    }
    get shouldUseFocusTrap() {
        return this.afShowDialog && this.focusableElements.length > 0;
    }
    get cssModifiers() {
        return {
            'digi-dialog--primary': this.afVariation == DialogVariation.PRIMARY,
            'digi-dialog--secondary': this.afVariation == DialogVariation.SECONDARY,
            'digi-dialog--small': this.afSize == DialogSize.SMALL,
            'digi-dialog--medium': this.afSize == DialogSize.MEDIUM,
            'digi-dialog--large': this.afSize == DialogSize.LARGE
        };
    }
    render() {
        return (h(Host, { key: '7645cdea8aa64030e5cdacc13d2b657ced71694d', ref: (el) => {
                this._host = el;
            } }, this.afShowDialog && (h("div", { key: '7956ce0de7909b54bd51a2a203f34239eea43f38', class: Object.assign({ 'digi-dialog': true }, this.cssModifiers) }, h("digi-util-keydown-handler", { key: 'd032d1a8b27b5cd88558c06d1a044dced2c0287c', onAfOnEsc: (e) => this.escHandler(e), onAfOnTab: (e) => this.tabHandler(e), onAfOnShiftTab: (e) => this.shiftHandler(e), class: "digi-dialog__keydown-handler" }, h("div", { key: '5eaa4f82217a657b8a956ca19620ce5ee4058651', ref: (el) => {
                this._wrapper = el;
            }, role: "dialog", "aria-modal": "true", class: "digi-dialog__content" }, h("digi-typography", { key: '08f9045a7fedc3127593a92e85dbdb08243cd7aa' }, this.afCloseButtonText && (h("digi-button", { key: '297e28a9840d4365a98b41d7ce0b704ba20c3632', ref: (el) => (this._closeButton = el), class: "digi-dialog__close-button", afAriaLabel: this.afCloseButtonText, afSize: ButtonSize.MEDIUM, "af-variation": "function", onAfOnClick: (e) => this.closeDialog(e) }, this.afCloseButtonText, h("digi-icon-x", { key: 'b21d15d15f96f30cfeba0cc952c99918dbe92f0d', class: "digi-dialog__close-icon", slot: "icon-secondary" }))), h("slot", { key: '9a17c4c0accd79502cd53d4f1a9b40bd24aa8f63', name: "over-heading" }), this.afHeadingLevel && this.afHeading && (h(this.afHeadingLevel, { key: '797db07e133f8e424972a22dc4cd9c0fff87c1ca', tabindex: "-1", ref: (el) => (this._dialogHeading = el) }, this.afHeading)), h("slot", { key: '228d808404637c354e80264d9a16accd07ef7038' }), h("div", { key: '3026af7da362dae66103f8bee7d0cf82d4b9d9bc', ref: (el) => (this._buttonContainer = el), class: "digi-dialog__button-container" }, this.afSecondaryButtonText && (h("digi-button", { key: '5799f15bee8a093981c7a2ee1746c3ebf5bcaaa4', ref: (el) => (this._secondaryButton = el), afVariation: ButtonVariation.SECONDARY, onAfOnClick: (e) => this.secondaryClickHandler(e) }, this.afSecondaryButtonText)), this.afPrimaryButtonText && (h("digi-button", { key: '78aa226ed8b00565138cdc52c50dbfc719c7775a', ref: (el) => (this._primaryButton = el), afVariation: ButtonVariation.PRIMARY, onAfOnClick: (e) => this.primaryClickHandler(e) }, this.afPrimaryButtonText))))))))));
    }
    static get is() { return "digi-dialog"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["dialog.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["dialog.css"]
        };
    }
    static get properties() {
        return {
            "afId": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "Input id attribute. Defaults to random string."
                        }],
                    "text": "S\u00E4tter attributet 'id'. Om inget v\u00E4ljs s\u00E5 skapas ett slumpm\u00E4ssigt id."
                },
                "getter": false,
                "setter": false,
                "attribute": "af-id",
                "reflect": false,
                "defaultValue": "randomIdGenerator('digi-dialog')"
            },
            "afVariation": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "DialogVariation",
                    "resolved": "DialogVariation.PRIMARY | DialogVariation.SECONDARY",
                    "references": {
                        "DialogVariation": {
                            "location": "import",
                            "path": "./dialog-variation.enum",
                            "id": "src/components/_dialog/dialog/dialog-variation.enum.ts::DialogVariation"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "Set variation to modal. Secondary is only in beta."
                        }],
                    "text": "S\u00E4tt variation p\u00E5 modalen. OBS! Sekund\u00E4r variant \u00E4r endast en beta."
                },
                "getter": false,
                "setter": false,
                "attribute": "af-variation",
                "reflect": false,
                "defaultValue": "DialogVariation.PRIMARY"
            },
            "afSize": {
                "type": "string",
                "mutable": true,
                "complexType": {
                    "original": "DialogSize",
                    "resolved": "DialogSize.LARGE | DialogSize.MEDIUM | DialogSize.SMALL",
                    "references": {
                        "DialogSize": {
                            "location": "import",
                            "path": "./dialog-size.enum",
                            "id": "src/components/_dialog/dialog/dialog-size.enum.ts::DialogSize"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "Set size of modal window."
                        }],
                    "text": "S\u00E4tt storlek p\u00E5 modalen\nsmall = max-width: 450px,\nmedium = max-width: 675px (standard),\nlarge = max-width: 900px"
                },
                "getter": false,
                "setter": false,
                "attribute": "af-size",
                "reflect": false,
                "defaultValue": "DialogSize.MEDIUM"
            },
            "afShowDialog": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "Set to true to activate modal window."
                        }],
                    "text": "S\u00E4tt till true om modalen ska visas"
                },
                "getter": false,
                "setter": false,
                "attribute": "af-show-dialog",
                "reflect": false
            },
            "afCloseButtonText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "Show close button"
                        }],
                    "text": "Visa st\u00E4ng-knapp"
                },
                "getter": false,
                "setter": false,
                "attribute": "af-close-button-text",
                "reflect": false,
                "defaultValue": "'St\u00E4ng'"
            },
            "afHeadingLevel": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "DialogHeadingLevel",
                    "resolved": "DialogHeadingLevel.H1 | DialogHeadingLevel.H2 | DialogHeadingLevel.H3 | DialogHeadingLevel.H4 | DialogHeadingLevel.H5 | DialogHeadingLevel.H6",
                    "references": {
                        "DialogHeadingLevel": {
                            "location": "import",
                            "path": "./dialog-heading-level.enum",
                            "id": "src/components/_dialog/dialog/dialog-heading-level.enum.ts::DialogHeadingLevel"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "Set heading level. Default is 'h2'"
                        }],
                    "text": "S\u00E4tt rubrikens vikt. 'h2' \u00E4r f\u00F6rvalt."
                },
                "getter": false,
                "setter": false,
                "attribute": "af-heading-level",
                "reflect": false,
                "defaultValue": "DialogHeadingLevel.H2"
            },
            "afHeading": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "The heading text"
                        }],
                    "text": "Text till rubrik"
                },
                "getter": false,
                "setter": false,
                "attribute": "af-heading",
                "reflect": false
            },
            "afPrimaryButtonText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "The primary button text"
                        }],
                    "text": "Text p\u00E5 prim\u00E4r knapp"
                },
                "getter": false,
                "setter": false,
                "attribute": "af-primary-button-text",
                "reflect": false
            },
            "afSecondaryButtonText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "The secondary button text"
                        }],
                    "text": "Text p\u00E5 sekund\u00E4r knapp"
                },
                "getter": false,
                "setter": false,
                "attribute": "af-secondary-button-text",
                "reflect": false
            },
            "afFallbackElementSelector": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "Use if you want to choose which element gets focused when modal is closed"
                        }],
                    "text": "Om man vill ha annat element \u00E4n sista aktiva elementet innan modalen \u00F6ppnades"
                },
                "getter": false,
                "setter": false,
                "attribute": "af-fallback-element-selector",
                "reflect": false
            }
        };
    }
    static get events() {
        return [{
                "method": "afPrimaryButtonClick",
                "name": "afPrimaryButtonClick",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "The primary buttons 'onclick' event"
                        }],
                    "text": "Prim\u00E4ra knappens 'onclick'-event"
                },
                "complexType": {
                    "original": "MouseEvent",
                    "resolved": "MouseEvent",
                    "references": {
                        "MouseEvent": {
                            "location": "global",
                            "id": "global::MouseEvent"
                        }
                    }
                }
            }, {
                "method": "afSecondaryButtonClick",
                "name": "afSecondaryButtonClick",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "The secondary buttons 'onclick' event"
                        }],
                    "text": "Sekund\u00E4ra knappens 'onclick'-event"
                },
                "complexType": {
                    "original": "MouseEvent",
                    "resolved": "MouseEvent",
                    "references": {
                        "MouseEvent": {
                            "location": "global",
                            "id": "global::MouseEvent"
                        }
                    }
                }
            }, {
                "method": "afOnClose",
                "name": "afOnClose",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "Event fired when modal is closed"
                        }],
                    "text": "Event n\u00E4r modalen st\u00E4ngs"
                },
                "complexType": {
                    "original": "MouseEvent",
                    "resolved": "MouseEvent",
                    "references": {
                        "MouseEvent": {
                            "location": "global",
                            "id": "global::MouseEvent"
                        }
                    }
                }
            }];
    }
    static get elementRef() { return "hostElement"; }
}
