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 { nothing, html } from 'lit';
import { property, state } from 'lit/decorators.js';
/**
 * Mixin that provides character limit / counter functionality.
 *
 * This mixin is shared between `mdc-input` and `mdc-textarea` components.
 * It provides:
 * - `maxCharacterLimit` and `characterLimitAnnouncement` properties
 * - Character overflow state tracking and `limitexceeded` event dispatching
 * - Screen reader announcement logic for character limit warnings
 * - `renderCharacterCounter()` method for rendering the counter UI
 *
 * The consuming component must:
 * - Have a `value` property (string)
 * - Have a `helpText` property (string)
 * - Call `handleCharacterOverflowStateChange()` when `value` changes
 * - Call `announceCharacterLimitWarning()` when `helpText` changes or value is updated
 *
 * @param superClass - The base class to extend.
 */
export const CharacterLimitMixin = (superClass) => {
    /**
     * @event limitexceeded - (React: onLimitExceeded) This event is dispatched once when the character limit
     * exceeds or restored.
     */
    class InnerMixinClass extends superClass {
        constructor() {
            super(...arguments);
            /**
             * @internal
             */
            this.characterLimitExceedingFired = false;
        }
        /**
         * Dispatches the character overflow state change event.
         * @internal
         */
        dispatchCharacterOverflowStateChangeEvent() {
            this.dispatchEvent(new CustomEvent('limitexceeded', {
                detail: {
                    currentCharacterCount: this.value.length,
                    maxCharacterLimit: this.maxCharacterLimit,
                    value: this.value,
                },
                bubbles: true,
                composed: true,
            }));
        }
        /**
         * Handles the character overflow state change.
         * Dispatches the character overflow state change event if the character limit is exceeded or restored.
         */
        handleCharacterOverflowStateChange() {
            if (this.maxCharacterLimit) {
                if (this.value.length > this.maxCharacterLimit && !this.characterLimitExceedingFired) {
                    this.dispatchCharacterOverflowStateChangeEvent();
                    this.characterLimitExceedingFired = true;
                }
                else if (this.value.length <= this.maxCharacterLimit && this.characterLimitExceedingFired) {
                    this.dispatchCharacterOverflowStateChangeEvent();
                    this.characterLimitExceedingFired = false;
                }
            }
        }
        /**
         * Announces the character limit warning based on the current value length.
         * If the value length exceeds the max character limit, the help text is announced (if help text is present).
         * If the value length does not exceed the max character limit, then the character limit announcement is announced.
         */
        announceCharacterLimitWarning() {
            this.characterLimitAriaLiveAnnouncer = '';
            if (!this.maxCharacterLimit || this.value.length === 0) {
                return;
            }
            if (this.helpText && this.value.length > this.maxCharacterLimit) {
                this.updateComplete
                    .then(() => {
                    this.characterLimitAriaLiveAnnouncer = this.helpText;
                })
                    .catch(() => { });
            }
            else if (this.characterLimitAnnouncement && this.value.length <= this.maxCharacterLimit) {
                this.characterLimitAriaLiveAnnouncer = this.characterLimitAnnouncement
                    .replace('%{number-of-characters}', this.value.length.toString())
                    .replace('%{max-character-limit}', this.maxCharacterLimit.toString());
            }
        }
        /**
         * Renders the character counter element.
         */
        renderCharacterCounter() {
            if (!this.maxCharacterLimit) {
                return nothing;
            }
            return html `
        <mdc-text part="character-counter" tagname="span" type="body-midsize-regular">
          ${this.value.length}/${this.maxCharacterLimit}
        </mdc-text>
      `;
        }
    }
    __decorate([
        property({ type: Number, attribute: 'max-character-limit' }),
        __metadata("design:type", Number)
    ], InnerMixinClass.prototype, "maxCharacterLimit", void 0);
    __decorate([
        property({ type: String, attribute: 'character-limit-announcement' }),
        __metadata("design:type", String)
    ], InnerMixinClass.prototype, "characterLimitAnnouncement", void 0);
    __decorate([
        state(),
        __metadata("design:type", String)
    ], InnerMixinClass.prototype, "characterLimitAriaLiveAnnouncer", void 0);
    return InnerMixinClass;
};
