// #region Imports
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 { Property } from '../../../Controls/Decorators/PropertyDecorator';
/**
 * @public
 */
// eslint-disable-next-line @typescript-eslint/naming-convention
export const Validateable = (base) => {
    class ValidateableElement extends base {
        // #region Fields
        _validator;
        _customValidationMessage = '';
        _validators;
        // #endregion
        // #region Ctor
        /**
         * Constructs a new instance of the `ValidateableElement` class.
         *
         * @public
         */
        constructor(...args) {
            super(args);
            this._validator = null;
            this._customValidationMessage = '';
            this._validators = [];
        }
        // #endregion
        // #region Properties
        /**
         * Gets or sets the `validators` property.
         *
         * @public
         */
        get validators() {
            return this._validators;
        }
        set validators(value) {
            if (this._validators !== value) {
                this._validators = value;
                this.requestUpdate('validators');
            }
        }
        /**
         * @public
         * @readonly
         */
        get validity() {
            // this.syncValidity();
            const validity = {
                badInput: this.internals.validity.badInput,
                customError: this.internals.validity.customError,
                patternMismatch: this.internals.validity.patternMismatch,
                rangeOverflow: this.internals.validity.rangeOverflow,
                rangeUnderflow: this.internals.validity.rangeUnderflow,
                stepMismatch: this.internals.validity.stepMismatch,
                tooLong: this.internals.validity.tooLong,
                tooShort: this.internals.validity.tooShort,
                typeMismatch: this.internals.validity.typeMismatch,
                valid: this.internals.validity.valid,
                valueMissing: this.internals.validity.valueMissing,
                mail: {
                    valid: true,
                    description: 'test'
                }
            };
            return validity;
        }
        /**
         * @public
         * @readonly
         */
        get validationMessage() {
            // this.syncValidity();
            return this.internals.validationMessage;
        }
        /**
         * @public
         * @readonly
         */
        get willValidate() {
            // this.syncValidity();
            return this.internals.willValidate;
        }
        /**
         * @public
         */
        getValidityAnchor() {
            return this;
        }
        /**
         * @public
         */
        checkValidity() {
            void this.syncValidity();
            return this.internals.checkValidity();
        }
        /**
         * @public
         */
        reportValidity() {
            void this.syncValidity();
            return this.internals.reportValidity();
        }
        /**
         * @public
         */
        setCustomValidity(error) {
            this._customValidationMessage = error;
            void this.syncValidity();
        }
        /**
         * @public
         */
        requestUpdate(name, oldValue, options) {
            super.requestUpdate(name, oldValue, options);
            void this.syncValidity();
        }
        /**
         * @public
         */
        firstUpdated(changed) {
            super.firstUpdated(changed);
            // Sync the validity again when the element first renders, since the
            // validity anchor is now available.
            // Elements that `delegatesFocus: true` to an `<input>` will throw an
            // error in Chrome and Safari when a form tries to submit or call
            // `form.reportValidity()`:
            // "An invalid form control with name='' is not focusable"
            // The validity anchor MUST be provided in `internals.setValidity()` and
            // MUST be the `<input>` element rendered.
            // See https://lit.dev/playground/#gist=6c26e418e0010f7a5aac15005cde8bde
            // for a reproduction.
            void this.syncValidity();
        }
        /**
         * @private
         */
        /**
         * Synchronizes the validity state of the element.
         * @returns A promise that resolves when the validity state has been synchronized.
         */
        async syncValidity() {
            return this.updateComplete.then(() => {
                this._validator ??= this.createValidator();
                this.validators.forEach((x) => {
                    this.addController(x(this));
                });
                const result = this._validator.getValidity();
                const hasCustomError = !!this._customValidationMessage;
                const validationMessage = this._customValidationMessage ?? result.validationMessage;
                this.internals.setValidity({
                    ...result.validity,
                    customError: hasCustomError
                }, validationMessage, this.getValidityAnchor() ?? undefined);
            });
        }
    }
    __decorate([
        Property({ type: (Array) }),
        __metadata("design:type", Array),
        __metadata("design:paramtypes", [Array])
    ], ValidateableElement.prototype, "validators", null);
    return ValidateableElement;
};
//# sourceMappingURL=Validateable.js.map