var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { html, nothing } from 'lit';
import { property, query, queryAssignedElements, state } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { Component } from '../../models';
import { FooterMixin } from '../../utils/mixins/FooterMixin';
import { TYPE } from '../text/text.constants';
import { hasOverflowMixin } from '../../utils/dom';
import { DEFAULTS } from './toast.constants';
import { getIconNameForVariant } from './toast.utils';
import styles from './toast.styles';
/**
 * `mdc-toast` is a lightweight, non-blocking alert used to inform users about application processes.
 * It supports success, warning, error, and custom messages, and is designed to be controlled externally.
 *
 * **Note**: When using `slot="toast-body-normal"` and `slot="toast-body-detailed"`, it's strongly recommended to wrap the content with `<mdc-text tagname="span">`.
 * If not used, ensure your custom content is styled appropriately to match the design and alignment expectations of the toast component.
 *
 * @dependency mdc-icon
 * @dependency mdc-text
 * @dependency mdc-button
 *
 * @slot content-prefix - Slot for custom content before the icon (only for custom variant).
 * @slot toast-body-normal - Slot for the main body content of the toast.
 * @slot toast-body-detailed - Slot for additional detailed content, shown when expanded.
 * @slot footer - Slot for custom footer content. Prefer using footer-button-primary and footer-button-secondary slots.
 * @slot footer-button-primary - Slot for passing the primary variant of `mdc-button` in the footer.
 * @slot footer-button-secondary - Slot for passing the secondary variant of `mdc-button` in the footer.
 *
 * @tagname mdc-toast
 *
 * @event close - (React: onClose) Dispatched when the Close Button is clicked using mouse or keyboard.
 *
 * @csspart content-container - The container for the toast's main content, including icon, text, and close button.
 * @csspart toast-prefix-icon - The icon shown at the start of the toast, styled by variant.
 * @csspart toast-content - The container for the header and body content of the toast.
 * @csspart toast-header - The header text of the toast.
 * @csspart footer - The container for the toast's footer, including toggle and action buttons.
 * @csspart footer-button-toggle - The toggle button for showing/hiding detailed content.
 * @csspart toast-close-btn - The close button for the toast.
 * @csspart has-footer-buttons - Applied to the footer when it contains buttons or a toggle button.
 *
 * @cssproperty --mdc-toast-background-color - Background color of the toast.
 * @cssproperty --mdc-toast-border-color - Border color of the toast.
 * @cssproperty --mdc-toast-header-text-color - Color of the header text in the toast.
 * @cssproperty --mdc-toast-icon-color - Color of the icon in the toast.
 * @cssproperty --mdc-toast-elevation-3 - Elevation effect applied to the toast.
 * @cssproperty --mdc-toast-width - Width of the toast.
 * @cssproperty --mdc-toast-padding - Padding inside the toast.
 */
class Toast extends FooterMixin(Component) {
    constructor() {
        super(...arguments);
        /**
         * Type of toast
         * - Can be `custom`, `success`, `warning` or `error`.
         *
         * Note: When using the `custom` variant, provide your own icon via the `content-prefix` slot; otherwise, no icon will be shown.
         * @default 'custom'
         */
        this.variant = DEFAULTS.VARIANT;
        /**
         * The html tag to be used for the header text
         * @default 'h2'
         */
        this.headerTagName = DEFAULTS.HEADER_TAG_NAME;
        /**
         * Defines aria-label attribute when header is not used
         */
        this.ariaLabel = null;
        this.isDetailVisible = false;
        this.hasDetailedSlot = false;
        /**
         * Indicates whether the header text is overflowing and requires the show more/less toggle button to be shown when detailed content is present.
         * This is determined on first update and will not update dynamically if the header text changes after initial render.
         * @internal
         */
        this.hasOverflowingHeaderText = false;
        this.hasFooterButtons = '';
    }
    /**
     * Fired when Close Button is clicked using mouse or keyboard.
     * This method dispatches the close event.
     * It is used to notify that the toast should be closed.
     */
    closeToast() {
        const closeEvent = new CustomEvent('close', {
            bubbles: true,
            composed: true,
            detail: { id: this.id },
        });
        this.dispatchEvent(closeEvent);
    }
    toggleDetailVisibility() {
        this.isDetailVisible = !this.isDetailVisible;
        if (this.isDetailVisible) {
            this.setAttribute('data-expanded', 'true');
        }
        else {
            this.removeAttribute('data-expanded');
        }
    }
    updateDetailedSlotPresence() {
        var _a, _b;
        this.hasDetailedSlot = (_b = (_a = this.detailedElements) === null || _a === void 0 ? void 0 : _a.some(el => { var _a; return (_a = el.textContent) === null || _a === void 0 ? void 0 : _a.trim(); })) !== null && _b !== void 0 ? _b : false;
    }
    updateFooterButtonsPresence() {
        var _a, _b, _c, _d;
        this.hasFooterButtons =
            ((_b = (_a = this.footerButtonPrimary) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0 ||
                ((_d = (_c = this.footerButtonSecondary) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0) > 0 ||
                this.shouldRenderToggleButton()
                ? 'has-footer-buttons'
                : '';
    }
    async firstUpdated(changedProperties) {
        super.firstUpdated(changedProperties);
        this.updateDetailedSlotPresence();
        await this.updateComplete;
        if (hasOverflowMixin(this.headerTextElement)) {
            this.hasOverflowingHeaderText = this.headerTextElement.isHeightOverflowing();
        }
    }
    renderIcon(iconName) {
        if (!iconName)
            return nothing;
        return html `
      <mdc-icon name="${iconName}" size="${DEFAULTS.PREFIX_ICON_SIZE}" part="toast-prefix-icon"></mdc-icon>
    `;
    }
    shouldRenderToggleButton() {
        return (this.hasDetailedSlot || this.hasOverflowingHeaderText) && this.showMoreText && this.showLessText;
    }
    renderToggleDetailButton() {
        if (!this.shouldRenderToggleButton())
            return nothing;
        return html `
      <mdc-button
        variant="tertiary"
        part="footer-button-toggle"
        @click="${this.toggleDetailVisibility}"
        postfix-icon="${this.isDetailVisible ? DEFAULTS.ARROW_UP_BOLD : DEFAULTS.ARROW_DOWN_BOLD}"
      >
        ${this.isDetailVisible ? this.showLessText : this.showMoreText}
      </mdc-button>
    `;
    }
    renderHeader() {
        return this.headerText
            ? html `
          <mdc-text part="toast-header" tagname="${this.headerTagName}" type="${TYPE.BODY_LARGE_BOLD}">
            ${this.headerText}
          </mdc-text>
        `
            : nothing;
    }
    handleFooterSlot(tagname, variant) {
        super.handleFooterSlot(tagname, variant);
        this.updateFooterButtonsPresence();
    }
    renderFooter() {
        this.updateFooterButtonsPresence();
        return html ` <slot name="footer">
      <div part="footer ${this.hasFooterButtons}">
        ${this.renderToggleDetailButton()}
        <slot
          name="footer-button-secondary"
          @slotchange=${() => this.handleFooterSlot(DEFAULTS.BUTTON, DEFAULTS.SECONDARY_BUTTON)}
        ></slot>
        <slot
          name="footer-button-primary"
          @slotchange=${() => this.handleFooterSlot(DEFAULTS.BUTTON, DEFAULTS.PRIMARY_BUTTON)}
        ></slot>
      </div>
    </slot>`;
    }
    render() {
        var _a;
        return html `
      <div part="content-container">
        ${this.variant === DEFAULTS.VARIANT
            ? html `<slot name="content-prefix"></slot>`
            : html `${this.renderIcon((_a = getIconNameForVariant(this.variant)) !== null && _a !== void 0 ? _a : '')}`}
        <div part="toast-content">
          ${this.renderHeader()}
          <slot name="toast-body-normal"></slot>
          <div ?hidden="${!this.isDetailVisible}">
            <slot name="toast-body-detailed"></slot>
          </div>
        </div>
        <mdc-button
          part="toast-close-btn"
          prefix-icon="${DEFAULTS.CANCEL_ICON}"
          variant="${DEFAULTS.TERTIARY_BUTTON}"
          size="${DEFAULTS.CLOSE_ICON_SIZE}"
          aria-label="${ifDefined(this.closeButtonAriaLabel)}"
          @click="${this.closeToast}"
        ></mdc-button>
      </div>
      ${this.renderFooter()}
    `;
    }
}
Toast.styles = [...Component.styles, ...styles];
__decorate([
    query("[part='toast-header']"),
    __metadata("design:type", HTMLElement)
], Toast.prototype, "headerTextElement", void 0);
__decorate([
    property({ type: String, reflect: true }),
    __metadata("design:type", String)
], Toast.prototype, "variant", void 0);
__decorate([
    property({ type: String, attribute: 'close-button-aria-label' }),
    __metadata("design:type", String)
], Toast.prototype, "closeButtonAriaLabel", void 0);
__decorate([
    property({ type: String, reflect: true, attribute: 'header-text' }),
    __metadata("design:type", String)
], Toast.prototype, "headerText", void 0);
__decorate([
    property({ type: String, reflect: true, attribute: 'header-tag-name' }),
    __metadata("design:type", String)
], Toast.prototype, "headerTagName", void 0);
__decorate([
    property({ type: String, reflect: true, attribute: 'aria-label' }),
    __metadata("design:type", Object)
], Toast.prototype, "ariaLabel", void 0);
__decorate([
    property({ type: String, reflect: true, attribute: 'show-more-text' }),
    __metadata("design:type", String)
], Toast.prototype, "showMoreText", void 0);
__decorate([
    property({ type: String, reflect: true, attribute: 'show-less-text' }),
    __metadata("design:type", String)
], Toast.prototype, "showLessText", void 0);
__decorate([
    state(),
    __metadata("design:type", Boolean)
], Toast.prototype, "isDetailVisible", void 0);
__decorate([
    state(),
    __metadata("design:type", Boolean)
], Toast.prototype, "hasDetailedSlot", void 0);
__decorate([
    state(),
    __metadata("design:type", Boolean)
], Toast.prototype, "hasOverflowingHeaderText", void 0);
__decorate([
    queryAssignedElements({ slot: 'toast-body-detailed', flatten: true }),
    __metadata("design:type", Array)
], Toast.prototype, "detailedElements", void 0);
__decorate([
    state(),
    __metadata("design:type", String)
], Toast.prototype, "hasFooterButtons", void 0);
export default Toast;
