var RibicaValidationMixin = {
  _updateState: function(prop, value, callback) {
    var newState = {};
    newState[prop] = value;
    this.setState(newState, function(){
      if(callback) {
        callback();
      }
    }.bind(this));
  },
  _validate: function(prop, value) {
    if(this.validations && this.validations[prop]) {
      var cb = function(err, revalidateFields) {
        var errors = this.state.errors || {};
        if (err !== undefined) {
          if(err.length > 0) {
            errors[prop] = err;
          } else {
            delete errors[prop];
          }
        } else {
          delete errors[prop];
        }
        this.setState({errors: errors});
        if (revalidateFields) {
          for(var i = 0; i < revalidateFields.length; i++) {
            this.validateField(revalidateFields[i], this.state[revalidateFields[i]]);
          }
        }
      }.bind(this);

      var immediateErrors = this.validations[prop](value, cb);
      cb(immediateErrors);
    }
  },
  handleChange: function(prop) {
    return function(event) {
      event.preventDefault();
      var target = event.target;
      this._updateState(prop, target.value, function(){
        this._validate(prop, target.value);
      }.bind(this));
    }.bind(this);

  },
  getValidationMessages:function(prop) {
    var errors = this.state.errors || {};
    return (errors[prop] || []);
  },
  validateField: function(field) {
    this._validate(field, this.state[field]);
  },
  validate: function() {
    for (var key in this.state) {
      if (this.state.hasOwnProperty(key)) {
        this._validate(key, this.state[key]);
      }
    }
    return this.isValid();
  },
  isValid: function() {
    var errors = this.state.errors || {};
    return Object.keys(errors).length === 0;
  },
  componentDidMount : function(){
    this.setState({errors: {}});
    if (this.validations) {
      var self = this;
      this.validations.getState = function() {
        return self.state;
      };
    }
  },
};

module.exports = RibicaValidationMixin;
