import { BehaviorSubject, Subject } from 'rxjs';
import { ErrorSubscriber, validate, ValidateOption, } from '../validate';
import { switchMap } from 'rxjs/operators';
import { None } from '../maybe';
import { MODEL_ID } from './is';
var BasicModel = (function () {
    function BasicModel(id) {
        this.id = id;
        this.validate$ = new Subject();
        this.validators = [];
        this.initialValue = None();
        this.destroyOnUnmount = false;
        this.subscriptions = [];
        this.error$ = new BehaviorSubject(null);
        this.subscriptions.push(this.validate$
            .pipe(switchMap(validate(this)))
            .subscribe(new ErrorSubscriber(this)));
    }
    Object.defineProperty(BasicModel.prototype, "value", {
        get: function () {
            return this._getValue$().value;
        },
        set: function (value) {
            this.patchValue(value);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(BasicModel.prototype, "form", {
        get: function () {
            var _a;
            return (_a = this.owner) === null || _a === void 0 ? void 0 : _a.form;
        },
        enumerable: false,
        configurable: true
    });
    BasicModel.prototype.dispose = function () {
        this.subscriptions.forEach(function (subscription) { return subscription.unsubscribe(); });
        this.subscriptions = [];
        this.owner = null;
        this.clear();
        this.clearError();
    };
    BasicModel.prototype.valid = function () {
        return this._getValid$().value;
    };
    BasicModel.prototype.triggerValidate = function (option) {
        var _this = this;
        var _a;
        if (this.owner !== this && !(option & ValidateOption.StopPropagation)) {
            var parentOption = option & ~ValidateOption.IncludeChildrenRecursively;
            (_a = this.owner) === null || _a === void 0 ? void 0 : _a.validate(parentOption);
        }
        return new Promise(function (resolve, reject) {
            _this.validate$.next({
                option: option,
                resolve: resolve,
                reject: reject,
            });
        });
    };
    Object.defineProperty(BasicModel.prototype, "error", {
        get: function () {
            return this.error$.getValue();
        },
        set: function (error) {
            this.error$.next(error);
        },
        enumerable: false,
        configurable: true
    });
    return BasicModel;
}());
BasicModel.prototype[MODEL_ID] = true;
export { BasicModel };
