import { h, } from "@stencil/core";
import translate from "../../global/translations";
import { SnackbarContainer } from "./container";
import { createRandomString } from "../../util/random-string";
const container = new SnackbarContainer();
const hideAnimationDuration = 300;
/**
 * A Snackbar –also known as "Toast"– is used to inform the end user
 * about an action or a process in the system.
 * The information could vary from announcing that a process has just started,
 * is taking place now, has ended, or has been interrupted or canceled.
 *
 * The information that you provide using a snackbar should be:
 * - temporary
 * - contextual
 * - short
 * - and most importantly, ignorable.
 *
 * It means if the user misses the information, it shouldn't be a big deal.
 *
 * :::note
 * If the information you want to display has a higher importance or priority,
 * and you need to make sure that the user takes an action to dismiss it,
 * consider using the [Banner](#/component/limel-banner/) component instead.
 * For more complex interactions and for delivering more detailed information,
 * [Dialog](#/component/limel-dialog/) is a better choice.
 * :::
 *
 * @exampleComponent limel-example-snackbar
 * @exampleComponent limel-example-snackbar-with-action
 * @exampleComponent limel-example-snackbar-with-changing-messages
 * @exampleComponent limel-example-snackbar-dismissible
 * @exampleComponent limel-example-snackbar-persistent
 * @exampleComponent limel-example-snackbar-persistent-non-dismissible
 */
export class Snackbar {
    constructor() {
        /**
         * `true` if the snackbar is open, `false` otherwise.
         */
        this.open = false;
        /**
         * The amount of time in milliseconds to show the snackbar.
         * If set to `-1`, the snackbar will be persistent.
         * This means:
         * - either the end user will need to close it manually,
         * which requires the `dismissible` property to be set to `true`.
         * - or the snackbar needs to be closed programmatically.
         */
        this.timeout = 5000;
        /**
         * When `true` displays a dismiss button on the snackbar,
         * allowing users to close it.
         */
        this.dismissible = true;
        /**
         * Defines the language for translations.
         */
        this.language = 'en';
        this.offset = 0;
        this.isOpen = false;
        this.closing = true;
        this.handleOpen = () => {
            if (this.isOpen) {
                return;
            }
            this.isOpen = true;
            this.closing = false;
            container.add(this.host);
            if (this.timeout && this.timeout !== -1) {
                this.timeoutId = window.setTimeout(this.handleClose, Math.max(this.timeout - hideAnimationDuration, hideAnimationDuration));
            }
        };
        this.handleClose = () => {
            if (!this.isOpen) {
                return;
            }
            this.closing = true;
            if (this.timeoutId) {
                clearTimeout(this.timeoutId);
                this.timeoutId = undefined;
            }
            setTimeout(() => {
                this.isOpen = false;
                container.remove(this.host);
                this.hide.emit();
                this.offset = 0;
            }, hideAnimationDuration);
        };
        this.handleClickAction = () => {
            this.action.emit();
        };
        this.snackbarId = createRandomString();
    }
    componentDidLoad() {
        if (this.open) {
            requestAnimationFrame(this.handleOpen);
        }
    }
    onChangeIndex(event) {
        event.stopPropagation();
        this.offset = event.detail;
    }
    watchOpen() {
        if (this.open) {
            this.handleOpen();
        }
        else {
            this.handleClose();
        }
        this.isOpen = this.open;
    }
    /**
     * Show the snackbar
     * @deprecated Use the `open` property instead.
     */
    async show() {
        console.warn('The `show` method in `limel-snackbar` is deprecated. Please use the `open` property instead.');
        if (!this.open) {
            this.handleOpen();
        }
    }
    render() {
        return (h("aside", { key: '325959bb9699eb9067483534cb7599fc22ce3858', popover: "manual", style: {
                '--snackbar-timeout': `${Math.max(this.timeout || 0, 0)}ms`,
                '--snackbar-distance-to-top-edge': `${this.offset}px`,
            }, class: {
                open: this.open,
                'is-closing': this.closing,
                'limel-portal--parent': true,
            }, id: this.snackbarId, role: this.setAriaRoles(), "aria-atomic": this.open ? 'true' : undefined, "aria-relevant": this.open ? 'additions' : undefined }, h("div", { key: '20522b3364e47a201f73fe9ab5e2ebc3e7cd81e6', class: "surface" }, h("div", { key: 'd5d7020b4d8dfe9032afe8d06080af8cdadc6f07', class: "label" }, this.message), this.renderActions(this.actionText), this.renderDismissButton(this.dismissible))));
    }
    setAriaRoles() {
        if (!this.open) {
            return;
        }
        if (!this.timeout || this.timeout === -1) {
            return 'alertdialog';
        }
        return 'status';
    }
    renderActions(actionText) {
        if (!actionText) {
            return;
        }
        return h("div", { class: "actions" }, this.renderActionButton(actionText));
    }
    renderActionButton(actionText) {
        if (!actionText) {
            return;
        }
        return (h("limel-button", { label: actionText, onClick: this.handleClickAction }));
    }
    renderDismissButton(dismissible) {
        if (!dismissible) {
            return;
        }
        const label = translate.get('snackbar.dismiss', this.language);
        return (h("div", { class: "dismiss" }, this.renderTimeoutVisualization(), h("limel-icon-button", { class: "dismiss-button", icon: "multiply", label: label, onClick: this.handleClose, "aria-controls": this.snackbarId })));
    }
    renderTimeoutVisualization() {
        if (!this.timeout || this.timeout === -1) {
            return;
        }
        return (h("svg", { width: "36", height: "36", viewBox: "0 0 36 36" }, h("circle", { r: "18", cx: "18", cy: "18", fill: "var(--track-color)" }), h("path", { class: "track", d: "M 18,18 m -16,0 a 16,16 0 1,0 32,0 a 16,16 0 1,0 -32,0", stroke: "var(--fill-color)" })));
    }
    static get is() { return "limel-snackbar"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["snackbar.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["snackbar.css"]
        };
    }
    static get properties() {
        return {
            "open": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "`true` if the snackbar is open, `false` otherwise."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "open",
                "defaultValue": "false"
            },
            "message": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The text message to display."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "message"
            },
            "timeout": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The amount of time in milliseconds to show the snackbar.\nIf set to `-1`, the snackbar will be persistent.\nThis means:\n- either the end user will need to close it manually,\nwhich requires the `dismissible` property to be set to `true`.\n- or the snackbar needs to be closed programmatically."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "timeout",
                "defaultValue": "5000"
            },
            "actionText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The text to display for the action button."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "action-text"
            },
            "dismissible": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "When `true` displays a dismiss button on the snackbar,\nallowing users to close it."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "dismissible",
                "defaultValue": "true"
            },
            "multiline": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "deprecated",
                            "text": "Setting this property no longer has any effect. The property will be removed in a future major version."
                        }],
                    "text": "Whether to show the snackbar with space for multiple lines of text"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "multiline"
            },
            "language": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "Languages",
                    "resolved": "\"da\" | \"de\" | \"en\" | \"fi\" | \"fr\" | \"nb\" | \"nl\" | \"no\" | \"sv\"",
                    "references": {
                        "Languages": {
                            "location": "import",
                            "path": "../date-picker/date.types",
                            "id": "src/components/date-picker/date.types.ts::Languages",
                            "referenceLocation": "Languages"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Defines the language for translations."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "language",
                "defaultValue": "'en'"
            }
        };
    }
    static get states() {
        return {
            "offset": {},
            "isOpen": {},
            "closing": {}
        };
    }
    static get events() {
        return [{
                "method": "action",
                "name": "action",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the action button is pressed"
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "hide",
                "name": "hide",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the snackbar hides itself"
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }];
    }
    static get methods() {
        return {
            "show": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Show the snackbar",
                    "tags": [{
                            "name": "deprecated",
                            "text": "Use the `open` property instead."
                        }]
                }
            }
        };
    }
    static get elementRef() { return "host"; }
    static get watchers() {
        return [{
                "propName": "open",
                "methodName": "watchOpen"
            }];
    }
    static get listeners() {
        return [{
                "name": "changeOffset",
                "method": "onChangeIndex",
                "target": undefined,
                "capture": false,
                "passive": false
            }];
    }
}
