import { MDCDialog } from "@material/dialog";
import { h, } from "@stencil/core";
import { isEqual } from "lodash-es";
import { dispatchResizeEvent } from "../../util/dispatch-resize-event";
import { createRandomString } from "../../util/random-string";
/**
 * :::note
 * Regarding the `close` event: When putting other elements that emit `close`
 * events inside a dialog, those events must be caught and stopped inside the
 * dialog. If not, they will bubble to the event handler listening for `close`
 * events on the dialog, which will close the dialog too.
 *
 * See the example _Nested `close` events_.
 * :::
 *
 * :::important
 * Are you developing for
 * [Lime CRM](https://www.lime-technologies.com/en/lime-crm/)? Please note that
 * you should use the [DialogRenderer](https://lundalogik.github.io/lime-web-components/versions/latest/interfaces/DialogRenderer.html)
 * from Lime Web Components to open dialogs in Lime CRM.
 * :::
 *
 * @exampleComponent limel-example-dialog-basic
 * @exampleComponent limel-example-dialog-nested-close-events
 * @exampleComponent limel-example-dialog-heading
 * @exampleComponent limel-example-dialog-heading-actions
 * @exampleComponent limel-example-dialog-form
 * @exampleComponent limel-example-dialog-size
 * @exampleComponent limel-example-dialog-fullscreen
 * @exampleComponent limel-example-dialog-closing-actions
 * @exampleComponent limel-example-dialog-action-buttons
 * @slot - Content to put inside the dialog
 * @slot header-actions - The dialog header buttons
 * @slot button - The dialog buttons
 */
export class Dialog {
    constructor() {
        /**
         * Set to `true` to make the dialog "fullscreen".
         */
        this.fullscreen = false;
        /**
         * `true` if the dialog is open, `false` otherwise.
         */
        this.open = false;
        /**
         * Defines which action triggers a close-event.
         */
        this.closingActions = {
            escapeKey: true,
            scrimClick: true,
        };
        this.handleMdcOpened = this.handleMdcOpened.bind(this);
        this.handleMdcClosed = this.handleMdcClosed.bind(this);
        this.handleMdcClosing = this.handleMdcClosing.bind(this);
    }
    connectedCallback() {
        this.initialize();
    }
    componentWillLoad() {
        this.id = createRandomString();
    }
    componentDidLoad() {
        this.initialize();
    }
    initialize() {
        const element = this.host.shadowRoot.querySelector('.mdc-dialog');
        if (!element) {
            return;
        }
        this.mdcDialog = new MDCDialog(element);
        if (this.open) {
            this.mdcDialog.open();
        }
        this.mdcDialog.listen('MDCDialog:opened', this.handleMdcOpened);
        this.mdcDialog.listen('MDCDialog:closed', this.handleMdcClosed);
        this.mdcDialog.listen('MDCDialog:closing', this.handleMdcClosing);
        this.setClosingActions();
    }
    disconnectedCallback() {
        this.mdcDialog.unlisten('MDCDialog:opened', this.handleMdcOpened);
        this.mdcDialog.unlisten('MDCDialog:closed', this.handleMdcClosed);
        this.mdcDialog.unlisten('MDCDialog:closing', this.handleMdcClosing);
        this.mdcDialog.destroy();
    }
    render() {
        return (h("div", { key: '748566bd65db98ee75a743a7deedc7d0c9f80a90', class: {
                'mdc-dialog': true,
                'full-screen': !!this.fullscreen,
            }, role: "alertdialog", "aria-modal": "true", "aria-labelledby": 'limel-dialog-title-' + this.id, "aria-describedby": 'limel-dialog-content-' + this.id }, h("input", { key: '15d2c40108a2348f54066eab22d507c6a9b3eda9', hidden: true, id: "initialFocusEl" }), h("div", { key: 'f46ee440d02b257bde93273936ce1dfe8dc324ea', class: "mdc-dialog__container" }, h("div", { key: '9ba9919b2b880039ede217c0608d9f780d6ca770', class: "mdc-dialog__surface" }, h("input", { key: '07bb68ae4c7b8d91cb7f0fd02105738160bd9e8f', type: "button", id: "initialFocusElement" }), this.renderHeading(), h("div", { key: '1729cb0f7f442b3ee56272387de42b462926275c', class: "mdc-dialog__content", id: 'limel-dialog-content-' + this.id }, h("slot", { key: 'a5554b316a4e57700a2902ae4499f594045f267d' })), this.renderFooter())), h("div", { key: '85ecb0922ece938a5de20b804b6a2590f98032df', class: "mdc-dialog__scrim" })));
    }
    watchHandler(newValue, oldValue) {
        if (oldValue === newValue) {
            return;
        }
        if (!this.mdcDialog) {
            return;
        }
        if (newValue) {
            this.mdcDialog.open();
        }
        else {
            this.mdcDialog.close();
        }
    }
    closingActionsChanged(newValue, oldValue) {
        if (isEqual(newValue, oldValue)) {
            return;
        }
        this.setClosingActions();
    }
    handleMdcOpened() {
        // When the opening-animation has completed, dispatch a
        // resize-event so that any content that depends on
        // javascript for layout has a chance to update to the
        // final layout of the dialog. /Ads
        const waitForUiToRender = 100;
        setTimeout(dispatchResizeEvent, waitForUiToRender);
    }
    handleMdcClosed() {
        if (this.open) {
            this.close.emit();
        }
        this.open = false;
    }
    handleMdcClosing() {
        this.closing.emit();
    }
    isDialogHeadingObject(heading) {
        return typeof heading === 'object' && !!heading.title;
    }
    renderHeading() {
        if (this.isDialogHeadingObject(this.heading)) {
            const { title, subtitle, supportingText, icon } = this.heading;
            return (h("limel-header", { icon: icon, heading: title, subheading: subtitle, supportingText: supportingText }, h("slot", { name: "header-actions", slot: "actions" })));
        }
        else if (typeof this.heading === 'string') {
            return (h("limel-header", { heading: this.heading }, h("slot", { name: "header-actions", slot: "actions" })));
        }
        return null;
    }
    renderFooter() {
        return (h("footer", { class: "mdc-dialog__actions" }, h("slot", { name: "button" })));
    }
    setClosingActions() {
        this.mdcDialog.scrimClickAction = '';
        if (this.closingActions.scrimClick) {
            this.mdcDialog.scrimClickAction = 'close';
        }
        this.mdcDialog.escapeKeyAction = '';
        if (this.closingActions.escapeKey) {
            this.mdcDialog.escapeKeyAction = 'close';
        }
    }
    static get is() { return "limel-dialog"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["dialog.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["dialog.css"]
        };
    }
    static get properties() {
        return {
            "heading": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string | DialogHeading",
                    "resolved": "DialogHeading | string",
                    "references": {
                        "DialogHeading": {
                            "location": "import",
                            "path": "./dialog.types",
                            "id": "src/components/dialog/dialog.types.ts::DialogHeading",
                            "referenceLocation": "DialogHeading"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The heading for the dialog, if any."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "heading"
            },
            "fullscreen": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set to `true` to make the dialog \"fullscreen\"."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "fullscreen",
                "defaultValue": "false"
            },
            "open": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "`true` if the dialog is open, `false` otherwise."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "open",
                "defaultValue": "false"
            },
            "closingActions": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "ClosingActions",
                    "resolved": "ClosingActions",
                    "references": {
                        "ClosingActions": {
                            "location": "import",
                            "path": "./dialog.types",
                            "id": "src/components/dialog/dialog.types.ts::ClosingActions",
                            "referenceLocation": "ClosingActions"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Defines which action triggers a close-event."
                },
                "getter": false,
                "setter": false,
                "defaultValue": "{\n        escapeKey: true,\n        scrimClick: true,\n    }"
            }
        };
    }
    static get events() {
        return [{
                "method": "close",
                "name": "close",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the dialog is closed from inside the component.\n(*Not* emitted when the consumer sets the `open`-property to `false`.)"
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "closing",
                "name": "closing",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the dialog is in the process of being closed."
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }];
    }
    static get elementRef() { return "host"; }
    static get watchers() {
        return [{
                "propName": "open",
                "methodName": "watchHandler"
            }, {
                "propName": "closingActions",
                "methodName": "closingActionsChanged"
            }];
    }
}
