import { __extends } from "tslib";
import { jsx as _jsx } from "react/jsx-runtime";
import { FormContext } from './formulr';
import { combineLatest, merge } from 'rxjs';
import { map } from 'rxjs/operators';
import { FormError } from './Error';
import { Component } from 'react';
function equal(a, b) {
    if (a === b) {
        return true;
    }
    if (a.length !== b.length) {
        return false;
    }
    for (var i = 0; i < a.length; i += 1) {
        if (a[i] !== b[i]) {
            return false;
        }
    }
    return true;
}
function pickError(errors) {
    for (var i = 0; i < errors.length; i += 1) {
        var error = errors[i];
        if (error) {
            return error;
        }
    }
    return null;
}
var CombineErrors = (function (_super) {
    __extends(CombineErrors, _super);
    function CombineErrors() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.$ = null;
        _this.$parent = null;
        _this.state = {
            error: null,
        };
        _this.parentChildrenChange = function (name) {
            var names = _this.props.names;
            if (!names || !names.includes(name)) {
                return;
            }
            _this.unsubscribe();
            _this.subscribe();
        };
        _this.setError = function (error) {
            _this.setState({
                error: error,
            });
        };
        return _this;
    }
    CombineErrors.prototype.subscribe = function () {
        var parent = this.context.parent;
        var _a = this.props, models = _a.models, names = _a.names;
        var fields = [];
        if (names) {
            for (var i = 0; i < names.length; i += 1) {
                var name_1 = names[i];
                var model = parent.get(name_1);
                if (model) {
                    fields.push(model);
                }
            }
        }
        if (models) {
            for (var i = 0; i < models.length; i += 1) {
                fields.push(models[i]);
            }
        }
        this.$ = combineLatest(fields.map(function (it) { return it.error$; }))
            .pipe(map(pickError))
            .subscribe(this.setError);
    };
    CombineErrors.prototype.unsubscribe = function () {
        if (this.$) {
            this.$.unsubscribe();
            this.$ = null;
        }
    };
    CombineErrors.prototype.shouldComponentUpdate = function (nextProps, nextState) {
        return nextProps !== this.props || nextState.error !== this.state.error;
    };
    CombineErrors.prototype.componentDidMount = function () {
        var parent = this.context.parent;
        this.subscribe();
        this.$parent = merge(parent.childRegister$, parent.childRemove$).subscribe(this.parentChildrenChange);
    };
    CombineErrors.prototype.componentDidUpdate = function (prevProps) {
        if (this.props !== prevProps) {
            if (!equal(prevProps.models || [], this.props.models || []) ||
                !equal(prevProps.names || [], this.props.names || [])) {
                this.unsubscribe();
                this.subscribe();
            }
        }
    };
    CombineErrors.prototype.componentWillUnmount = function () {
        this.unsubscribe();
        if (this.$parent) {
            this.$parent.unsubscribe();
            this.$parent = null;
        }
    };
    CombineErrors.prototype.render = function () {
        var children = this.props.children;
        var error = this.state.error;
        if (children) {
            return children(error);
        }
        if (error === null) {
            return null;
        }
        return _jsx(FormError, { children: error === null || error === void 0 ? void 0 : error.message }, void 0);
    };
    CombineErrors.contextType = FormContext;
    return CombineErrors;
}(Component));
export { CombineErrors };
