// #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 { Focusable } from '../../../Behaviors/Focusable';
import { Attribute } from '../../../Decorators/AttributeDecorator';
import { Property } from '../../../Decorators/PropertyDecorator';
import { InputState } from '../../../Types/InputState';
import { CustomElement } from '../../Abstracts/CustomElement';
/**
 * Input base - The base class for all input elements.
 *
 * @public
 * @abstract
 */
export class InputBaseElement extends Focusable(CustomElement) {
    // #region Fields
    _state;
    _disabled;
    _formatter;
    _parser;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._state = InputState.Initial;
        this._disabled = false;
        this._formatter = null;
        this._parser = null;
    }
    // #endregion
    // #region Properties
    /**
     * Gets or sets the `disabled` property.
     *
     * @public
     * @attr
     */
    get disabled() {
        return this._disabled;
    }
    set disabled(value) {
        if (this._disabled !== value) {
            this._disabled = value;
            this.requestUpdate('disabled');
        }
    }
    /**
     * Gets or sets the `state` property.
     *
     * @public
     * @readonly
     * @attr
     */
    get state() {
        return this._state;
    }
    set state(value) {
        if (this._state !== value) {
            this._state = value;
            this.requestUpdate('state');
        }
    }
    /**
     * Gets or sets the `formatter` property.
     *
     * @public
     */
    get formatter() {
        return this._formatter;
    }
    set formatter(value) {
        if (this._formatter !== value) {
            this._formatter = value;
            this.requestUpdate('formatter');
        }
    }
    /**
     * Gets or sets the `parser` property.
     *
     * @public
     */
    get parser() {
        return this._parser;
    }
    set parser(value) {
        if (this._parser !== value) {
            this._parser = value;
            this.requestUpdate('parser');
        }
    }
    // #endregion
    // #region Methods
    /**
     * Resets the value of the element.
     *
     * @public
     */
    reset() {
        this.state = InputState.Initial;
    }
    /**
     * @protected
     */
    validate(input) {
        if (this.hasValidators() && !input.checkValidity()) {
            return false;
        }
        return true;
    }
    /**
     * @protected
     */
    onBlur(_event) {
        this.isFocused = false;
        let state = InputState.Initial;
        if (this.hasValidators() && !this.tryGetInput()?.checkValidity()) {
            state = InputState.Invalid;
        }
        if (state !== this._state) {
            this.state = state;
        }
    }
    /**
     * @protected
     */
    onInput(_event) {
        this.invalidate();
    }
    /**
     * @protected
     */
    onFocus(_event) {
        this.isFocused = true;
    }
    /**
     * @private
     */
    invalidate() {
        let state = InputState.Initial;
        if (!this.disabled && this.hasValidators()) {
            // native validation
            state = this.isFocused
                ? this.tryGetInput()?.checkValidity()
                    ? InputState.Valid
                    : InputState.Initial
                : InputState.Initial;
            if (state !== this._state) {
                this.state = state;
                // this._stateChanged.emit({ sender: this, state: this._state });
            }
        }
    }
    /**
     * @private
     */
    hasValidators() {
        const defaultValidationAttributes = [
            'required',
            'pattern',
            'minlength',
            'maxlength',
            'min',
            'max',
            'step'
        ];
        for (const attr of defaultValidationAttributes) {
            if (this.hasAttribute(attr)) {
                return true;
            }
        }
        return false;
    }
    /**
     * @private
     */
    tryGetInput() {
        const input = this.shadowRoot
            ? this.shadowRoot.querySelector('input') ?? this.shadowRoot.querySelector('textarea')
            : null;
        return input;
    }
}
__decorate([
    Attribute({
        type: Boolean,
        useDefault: true
    }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], InputBaseElement.prototype, "disabled", null);
__decorate([
    Attribute({ type: InputState }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], InputBaseElement.prototype, "state", null);
__decorate([
    Property({ type: Function }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], InputBaseElement.prototype, "formatter", null);
__decorate([
    Property({ type: Function }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], InputBaseElement.prototype, "parser", null);
/**
 * @public
 */
export function isInputBase(element) {
    return element instanceof InputBaseElement;
}
//# sourceMappingURL=InputBase.js.map