'use strict';

exports.__esModule = true;

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/* eslint-disable no-param-reassign */
var FormState = function FormState(fields) {
  var _this = this;

  var object = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var onChange = arguments[2];

  _classCallCheck(this, FormState);

  _initialiseProps.call(this);

  this.fields = fields;
  this.validator = {
    set: function set(obj, prop, value) {
      if (Array.isArray(value)) {
        obj[prop] = value.map(function (v) {
          return new Proxy(v, _this.validator);
        });
      } else if (value !== null && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {
        obj[prop] = new Proxy(value, _this.validator);
      } else {
        obj[prop] = value;
      }
      if (onChange) {
        onChange(prop, value, object);
      }
      return true;
    }
  };
  this.proxyObj = new Proxy(object, this.validator);
};

var _initialiseProps = function _initialiseProps() {
  var _this2 = this;

  this.get = function () {
    return _this2.proxyObj;
  };

  this.updateFields = function (fields) {
    _this2.fields = fields;
  };

  this.getErrors = function () {
    var errors = {};
    var addError = function addError(key, field, message) {
      if (!errors[key]) {
        errors[key] = [];
      }
      var msg = void 0;
      if (typeof message === 'function') {
        msg = message(field.description || field.label || key);
      } else {
        msg = message;
      }
      errors[key].push(msg);
    };
    Object.keys(_this2.fields).forEach(function (key) {
      var field = _this2.fields[key];
      var rules = field.validation;
      if (rules) {
        if (!Array.isArray(rules)) {
          rules = [rules];
        }

        var _loop = function _loop(i) {
          var rule = rules[i];
          if (typeof rule === 'function') {
            var value = _this2.proxyObj[key];
            if (Array.isArray(value)) {
              var arrayErrors = [];
              value.forEach(function (v, index) {
                var message = rule(_this2.proxyObj, _this2.proxyObj[key], index);
                if (message) {
                  arrayErrors[index] = message;
                }
              });
              if (arrayErrors.length) {
                addError(key, field, arrayErrors);
              }
            } else {
              var message = rule(_this2.proxyObj, _this2.proxyObj[key]);
              if (message) {
                addError(key, field, message);
              }
            }
          } else if (rule !== null && (typeof rule === 'undefined' ? 'undefined' : _typeof(rule)) === 'object') {
            if (rule.rule && typeof rule.rule === 'function') {
              var isValid = rule.rule(_this2.proxyObj, _this2.proxyObj[key]);
              if (!isValid) {
                if (typeof rule.message === 'function') {
                  addError(key, field, rule.message(field.label || key));
                } else {
                  addError(key, field, rule.message);
                }
              }
            }
          }
        };

        for (var i = 0; i < rules.length; i += 1) {
          _loop(i);
        }
      }
    });
    return errors;
  };

  this.isValid = function () {
    return !Object.keys(_this2.getErrors()).length;
  };
};

exports.FormState = FormState;