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;
};
import { property } from 'lit/decorators.js';
import { isFunction, isString } from '../../util.js';
function BaseFormAssociated(base) {
    class BaseFormAssociatedElement extends base {
        get __validators() {
            return [];
        }
        set disabled(value) {
            this._disabled = value;
            this.toggleAttribute('disabled', Boolean(this._disabled));
        }
        get disabled() {
            return this._disabled;
        }
        set invalid(value) {
            this._invalid = value;
            this.toggleAttribute('invalid', Boolean(this._invalid));
        }
        get invalid() {
            return this._invalid;
        }
        get form() {
            return this.__internals.form;
        }
        get validity() {
            return this.__internals.validity;
        }
        get validationMessage() {
            return this.__internals.validationMessage;
        }
        get willValidate() {
            return this.__internals.willValidate;
        }
        constructor(...args) {
            super(args);
            this._disabled = false;
            this._invalid = false;
            this._dirty = false;
            this._pristine = true;
            this.__internals = this.attachInternals();
            this.addEventListener('invalid', this._handleInvalid);
        }
        connectedCallback() {
            super.connectedCallback();
            this._dirty = false;
            this._updateValidity();
        }
        _handleInvalid(event) {
            event.preventDefault();
            this.invalid = true;
        }
        _setInvalidState() {
            if (this._dirty || !this._pristine) {
                this.invalid = !this.checkValidity();
            }
        }
        __runValidators() {
            const validity = {};
            let message = '';
            for (const validator of this.__validators) {
                const isValid = validator.isValid(this);
                validity[validator.key] = !isValid;
                if (!isValid) {
                    message = isFunction(validator.message)
                        ? validator.message(this)
                        : validator.message;
                }
            }
            return { validity, message };
        }
        _setDefaultValue(current) {
            this._formValue.defaultValue = current;
        }
        _restoreDefaultValue() {
            this._formValue.setValueAndFormState(this._formValue.defaultValue);
            this._updateValidity();
            this.requestUpdate();
        }
        _validate(message) {
            this._updateValidity(message);
            this._setInvalidState();
        }
        _updateValidity(error) {
            let { validity, message } = this.__runValidators();
            const hasCustomError = this.validity.customError;
            if (validity.valueMissing) {
                validity = {
                    valueMissing: true,
                    customError: hasCustomError,
                };
            }
            if (hasCustomError && error === undefined) {
                validity.customError = true;
                message = this.validationMessage;
            }
            else if (hasCustomError && error === '') {
                validity.customError = false;
            }
            else if (error && error !== '') {
                validity.customError = true;
                message = error;
            }
            this.__internals.setValidity(validity, message);
        }
        _setFormValue(value, state) {
            this._pristine = false;
            this.__internals.setFormValue(value, state);
        }
        formAssociatedCallback(_form) { }
        formDisabledCallback(state) {
            this._disabled = state;
            this.requestUpdate();
        }
        formResetCallback() {
            this._restoreDefaultValue();
            this._pristine = true;
            this._dirty = false;
            this.invalid = false;
        }
        formStateRestoreCallback(_state, _mode) { }
        reportValidity() {
            const state = this.__internals.reportValidity();
            this.invalid = !state;
            return state;
        }
        checkValidity() {
            const state = this.__internals.checkValidity();
            this.invalid = !state;
            return state;
        }
        setCustomValidity(message) {
            this._updateValidity(message);
        }
    }
    BaseFormAssociatedElement.formAssociated = true;
    __decorate([
        property({ reflect: true })
    ], BaseFormAssociatedElement.prototype, "name", void 0);
    __decorate([
        property({ type: Boolean, reflect: true })
    ], BaseFormAssociatedElement.prototype, "disabled", null);
    __decorate([
        property({ type: Boolean, reflect: true })
    ], BaseFormAssociatedElement.prototype, "invalid", null);
    return BaseFormAssociatedElement;
}
export function FormAssociatedMixin(base) {
    class FormAssociatedElement extends BaseFormAssociated(base) {
        set defaultValue(value) {
            this._formValue.defaultValue = value;
            if (this._pristine && 'value' in this) {
                this.value = this.defaultValue;
                this._pristine = true;
                this._validate();
            }
        }
        get defaultValue() {
            return this._formValue.defaultValue;
        }
        attributeChangedCallback(name, prev, current) {
            super.attributeChangedCallback(name, prev, current);
            if (name === 'value') {
                this._setDefaultValue(current);
            }
        }
    }
    __decorate([
        property({ attribute: false })
    ], FormAssociatedElement.prototype, "defaultValue", null);
    return FormAssociatedElement;
}
export function FormAssociatedCheckboxMixin(base) {
    class FormAssociatedCheckboxElement extends BaseFormAssociated(base) {
        set defaultChecked(value) {
            this._formValue.defaultValue = value;
            if (this._pristine && 'checked' in this) {
                this.checked = this.defaultChecked;
                this._pristine = true;
                this._validate();
            }
        }
        get defaultChecked() {
            return this._formValue.defaultValue;
        }
        attributeChangedCallback(name, prev, current) {
            super.attributeChangedCallback(name, prev, current);
            if (name === 'checked') {
                this._setDefaultValue(isString(current) ? 'true' : null);
            }
        }
    }
    __decorate([
        property({ attribute: false })
    ], FormAssociatedCheckboxElement.prototype, "defaultChecked", null);
    return FormAssociatedCheckboxElement;
}
//# sourceMappingURL=associated.js.map