import React from 'react';

export default Base => {
    return class extends React.Component {
        constructor(props, context) {
            super(props, context);

            this.state = {
                isValidating: false,
                isValid: true,
                validationErrorMessage: null
            };
        }

        componentWillReceiveProps(nextProps) {
            if (nextProps.value !== this.props.value) {
                this.setState({
                    isValidating: true
                }, () => {
                    this._validate(nextProps.value);
                });
            }
        }

        _callOnStart() {
            if ('onStart' in this.props) {
                this.props.onStart();
            }
        }

        _callOnEnd() {
            if ('onEnd' in this.props) {
                this.props.onEnd(this.state.isValid, this.state.validationErrorMessage);
            }
        }

        _onResolve(value) {
            if (value === this.props.value) {
                this.setState({
                    isValid: true,
                    isValidating: false,
                    validationErrorMessage: null
                }, this._callOnEnd);
            }
        }

        _onCatch(value, message) {
            if (value === this.props.value) {
                this.setState({
                    isValid: false,
                    isValidating: false,
                    validationErrorMessage: message
                }, this._callOnEnd);
            }
        }

        _validate(value) {
            this._callOnStart();

            Promise
                .all(
                    this.props.validators.map(validator => {
                        return validator.validator(value, validator.params);
                    })
                )
                .then(
                    this._onResolve.bind(this, value),
                    this._onCatch.bind(this, value)
                );
        }

        render() {
            return React.createElement(
                Base,
                {
                    ...this.props,
                    ...this.state
                },
                this.props.children
            );
        }
    }
}

@@ -2233,7 +2233,9 @@
    %7D
+;
 %0A%7D
+;
 %0A

fix ESLint errors