"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

var _typeof = require("@babel/runtime/helpers/typeof");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.FormChef = FormChef;
exports.default = void 0;

var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));

var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));

var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));

var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));

var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));

var _react = _interopRequireWildcard(require("react"));

var _utils = _interopRequireDefault(require("../utils/utils"));

var _FormChefCommon = _interopRequireDefault(require("../FormChefCommon"));

var _FormTombStone = _interopRequireWildcard(require("../FormTombStone"));

var _WebFormPie = _interopRequireDefault(require("./WebFormPie"));

var _Field = _interopRequireWildcard(require("./Field"));

var _generateValidator = _interopRequireDefault(require("./generateValidator"));

var _lodash = _interopRequireDefault(require("lodash"));

var _dependenceFieldsSort = _interopRequireDefault(require("../utils/dependenceFieldsSort"));

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }

function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }

var H5 = 'H5',
    WEB = 'WEB';

var RootFormDish = function RootFormDish(props) {
  return /*#__PURE__*/_react.default.createElement("span", null, "invalid form element");
};

var platform = _utils.default.isDeskTop() ? WEB : H5;

function defineDish(obj) {
  RootFormDish = obj;
}

function definePlatform(_platform) {
  platform = _platform;
}
/* 构件变动数值引发的依赖树，提出无关的依赖数据 */


function buildDependTree(changeValues, theFormulaSet) {
  var dependenceNet = {};

  _lodash.default.forEach(changeValues, function (v, k) {
    dependenceNet[k] = [];
  });

  var tempReferNames = Object.keys(changeValues);
  var maxLoop = 1000; //防止死循环

  var count = 0;

  while (true) {
    if (count > maxLoop) {
      console.warn("buildDependTree up to maxium loops(".concat(maxLoop, ")"));
      break;
    }

    var loopResult = findNextFormula(tempReferNames, theFormulaSet, dependenceNet);

    if (loopResult && loopResult.length > 0) {
      tempReferNames = loopResult;
    } else {
      break;
    }

    count++;
  }

  return dependenceNet;

  function findNextFormula() {
    var referNames = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
    var formulaSet = arguments.length > 1 ? arguments[1] : undefined;
    var linkedNest = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
    var nextReferNames = [];

    _lodash.default.forEach(referNames, function (referName) {
      _lodash.default.forEach(formulaSet, function (formula, targetName) {
        if (_lodash.default.includes(formula.referenceFields, referName)) {
          if (!nextReferNames.includes(targetName)) nextReferNames.push(targetName);

          if (linkedNest[targetName]) {
            if (!linkedNest[targetName].includes(referName)) {
              linkedNest[targetName] = linkedNest[targetName].concat(referName);
            }
          } else {
            linkedNest[targetName] = [referName];
          }
        }
      });
    });

    return nextReferNames;
  }
}
/* 拓扑次序数组 */


function topologicalOrder(theFormulaSet) {
  var changeValues = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var result = {
    status: 'fail',
    tOrder: []
  };
  var expLoopTree = [],
      triggerFields = Object.keys(changeValues);
  var pastReferFields = [],
      lastReferFields = [];

  _lodash.default.forEach(theFormulaSet, function (v, k) {
    expLoopTree.push({
      field: k,
      referFields: v.referenceFields
    });
  });

  var hasRecycle = _utils.default.isRecycle(expLoopTree, triggerFields);

  if (hasRecycle) {
    result.message = 'recycle in dependence';
    return result;
  } else {
    var dpFields = [];
    var dpTree = buildDependTree(changeValues, theFormulaSet);

    _lodash.default.forEach(dpTree, function (v, k) {
      dpFields.push({
        identifier: k,
        referFields: v
      });
    });

    var fieldSort = new _dependenceFieldsSort.default();
    fieldSort.buildGraph(dpFields);
    result.tOrder = fieldSort.sortedList;
    /* NOTE 过滤每一层中多余的referFields */

    _lodash.default.forEach(result.tOrder, function (sortList) {
      var thisLevelFields = [];

      _lodash.default.forEach(sortList, function (s) {
        thisLevelFields.push(s.identifier);
        var newReferFields = [];

        _lodash.default.forEach(s.referFields, function (f) {
          if (lastReferFields.includes(f)) {
            //包含再上一层的identifier列表中
            newReferFields.push(f);
          } else if (!pastReferFields.includes(f)) {
            //不包含历史的identifier列表中
            newReferFields.push(f);
          }
        });

        s.referFields = newReferFields;
      });

      lastReferFields = thisLevelFields;
      pastReferFields = pastReferFields.concat(thisLevelFields);
    });

    result.status = 'success';
    return result;
  }
}

var HocFormChef = function HocFormChef(option) {
  return function (WrappedComponent) {
    var defaultFormOption = {
      cookerOption: {
        validateMessages: {
          required: function required() {
            return '此项是必填项';
          },
          string: {
            max: function max(name, maxLength) {
              return "\u6700\u957F".concat(maxLength, "\u4E2A\u5B57\u7B26");
            }
          }
        }
      },
      formReadyLock: true,
      preDefinedFormulas: [],
      //某一种类型表单固有的联动公式关系
      isValueMap: false,
      //谨慎使用,        
      fieldMapsPlus: {},
      //用于额外添加fieldMap的映射，不覆盖公用的fieldMaps,用于区别不同表单的配置差异化
      fieldMaps: {},
      debug: false
    };
    var formOption = Object.assign({}, defaultFormOption, option);
    var FormDish = formOption.FormDish ? formOption.FormDish : RootFormDish;

    var WrapperFormChef = /*#__PURE__*/function (_Component) {
      (0, _inherits2.default)(WrapperFormChef, _Component);

      var _super = _createSuper(WrapperFormChef);

      function WrapperFormChef(props) {
        var _this;

        (0, _classCallCheck2.default)(this, WrapperFormChef);
        _this = _super.call(this, props);
        /* NOTE 状态管理需要非常谨慎，为了不滥用组件的更新，formchef的UI更新都通过forceUpdate执行 */

        _this.debugConsole = function (message) {
          var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';

          if (formOption.debug) {
            console.log("------".concat(message), data);
          }
        };

        _this.updateFormFields = function (fields) {
          var formDataChangeSilence = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
          var effectedFieldValues = {};
          if (_lodash.default.isEmpty(fields)) return;

          if (_this.state.formMode === 'EDIT') {
            _lodash.default.forEach(fields, function (field) {
              if (field.property.isFieldHide && _this.getFieldValue(field.identifier)) {
                effectedFieldValues[field.identifier] = undefined;
              }
            });
          }

          _this.setState(function (_ref) {
            var formFields = _ref.formFields;
            var cloneFormFields = (0, _toConsumableArray2.default)(formFields);
            var updateFlag = false;

            _lodash.default.forEach(fields, function (f) {
              var index = _lodash.default.findIndex(cloneFormFields, {
                identifier: f.identifier
              });

              if (index > -1) {
                updateFlag = true;
                cloneFormFields[index] = f;
              }
            });

            _this.debugConsole('Update formfield:the new formFields is', updateFlag ? cloneFormFields : formFields);

            return {
              formFields: updateFlag ? cloneFormFields : formFields
            };
          }, function () {
            _this.updateFieldInstance(fields);

            if (!_lodash.default.isEmpty(effectedFieldValues)) {
              if (!formDataChangeSilence) {
                _this.setFieldsValue(effectedFieldValues);
              } else {
                _this.modifyFormData(effectedFieldValues);
              }
            }
          });
        };

        _this.getFieldError = function (name) {
          var matchField = _this.fields[name];

          if (matchField) {
            return matchField.validateError;
          }
        };

        _this.setFormReady = function (val) {
          if (formOption.formReadyLock) {
            _this.setState({
              formReady: !!val
            });
          }
        };

        _this.setFieldsValue = function (changeValues) {
          var modifyOption = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
          if (!changeValues || _lodash.default.isEmpty(changeValues)) return;
          var blockChangeEffect = modifyOption.blockChangeEffect,
              modifyFromProps = modifyOption.modifyFromProps,
              blockValidate = modifyOption.blockValidate;
          var _this$state = _this.state,
              formReady = _this$state.formReady,
              formMode = _this$state.formMode,
              formFields = _this$state.formFields;

          var formData = _this.getFieldsValue();

          _this.debugConsole('Monitor Field Change');

          _this.debugConsole('Field Change:changeValues = ', changeValues);

          _this.debugConsole('Field Change:change options = ', modifyOption); //当字段的改变是单个的时候，需要判断改动的值和原来的值是否一致，一致就无需改动（性能优化）


          if (Object.keys(changeValues).length === 1) {
            var changeFieldKey = Object.keys(changeValues)[0];

            if (_lodash.default.isEqual(formData[changeFieldKey], changeValues[changeFieldKey])) {
              return;
            }
          }
          /* 直接触发的修改，提前处理，表单的联动处理统一成异步的方式，所以存在延后的可能性，UI上提早体现直接改变的值 */


          _this.modifyFormData(_objectSpread({}, changeValues), modifyFromProps ? false : true);

          var _afterChange = function _afterChange(effectedFormData) {
            _this.debugConsole('Field Change:Side effected field values are ', effectedFormData); // 新建状态下也是需要触发条件公式的        


            _this.fieldChangeOnCondition(_objectSpread(_objectSpread({}, formData), effectedFormData), effectedFormData);

            var identifierList = []; //NOTE 触发watch函数，如果表单是查看模式或者formReady=false的情况，不触发观察函数                    

            if (formMode === 'EDIT' && formReady) {
              _lodash.default.forEach(effectedFormData, function (value, key) {
                identifierList.push(key);

                if (key in _this.fields) {
                  var fieldInstance = _this.fields[key];
                  if (!blockValidate) fieldInstance.validate();

                  _lodash.default.forEach(fieldInstance.watch, function (item) {
                    if (typeof item === 'function') {
                      item(value, formData);
                    }
                  });
                }
                /* ANCHOR 逻辑说明
                    blockValidate权限最大
                    在非阻止校验的情况下，字段有错误信息，一定要校验
                    在非阻止校验的情况下，validateTrigger（校验方式）=onChange，才做校验
                */


                if (!blockValidate) {
                  //this.fields[key].validateError
                  var field = _lodash.default.find(formFields, {
                    identifier: key
                  });

                  var _ref2 = field || {},
                      _ref2$validateTrigger = _ref2.validateTrigger,
                      validateTrigger = _ref2$validateTrigger === void 0 ? 'onChange' : _ref2$validateTrigger;

                  if (_this.fields[key] && _this.fields[key].validateError) {
                    _this.validateField(key, value);
                  } else if (validateTrigger === 'onChange') {
                    _this.validateField(key, value);
                  }
                }
              });
            } //更新联动后的数据


            var nextChangeValues = {};

            _lodash.default.forEach(effectedFormData, function (v, k) {
              if (!_lodash.default.has(changeValues, k)) {
                nextChangeValues[k] = v;
              }
            });

            if (!_lodash.default.isEmpty(nextChangeValues)) _this.modifyFormData(nextChangeValues);
          };
          /* 同步联动公式执行优化 */
          //如果表单是查看模式||formReady=false||blockChangeEffect（明确改值不需要联动）的情况，不触发表单联动


          if (!blockChangeEffect && formMode === 'EDIT' && formReady) {
            try {
              _this.debugConsole('Field Change:Detect formula trigger');

              _this.triggerFormChain(formData, changeValues, function (formulaEffectedData) {
                /* REVIEW 临时修复，当公式运行后的对象字段是金额时，需要填充金额的币种信息 */
                _lodash.default.forEach(formulaEffectedData, function (v, k) {
                  if (k in changeValues) return;

                  var field = _lodash.default.find(formFields, {
                    identifier: k
                  });

                  var fieldValue = formData[k];

                  if (field && field.type === 'AmountInput' && _lodash.default.isNumber(v)) {
                    formulaEffectedData[k] = _objectSpread(_objectSpread({
                      currency: 'CNY'
                    }, _lodash.default.isObject(fieldValue) ? fieldValue : {}), {}, {
                      amount: v
                    });
                  }
                });

                _afterChange(formulaEffectedData);
              });
            } catch (err) {
              console.log(err);
            }
          }
        };

        _this.getFieldValue = function (name) {
          if (name) {
            var result = _this.getFieldInfo(name);

            if (result.code === 'success') return result.value;
          }
        };

        _this.modifyFormData = function (changeValues) {
          var needUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
          var _this$props = _this.props,
              formChange = _this$props.formChange,
              onChange = _this$props.onChange;

          var formData = _this.getFieldsValue();

          _this.formChefParser.updateParserPool({
            pool: _objectSpread(_objectSpread({}, formData), changeValues)
          });

          if (formOption.isValueMap) {
            if (needUpdate) {
              if (typeof onChange === 'function') onChange(_objectSpread(_objectSpread({}, formData), changeValues));
            }
          }

          _lodash.default.forEach(changeValues, function (val, key) {
            if (_this.fields[key]) {
              _this.fields[key].setValue(val);
            }
          });
          /* 表单值改变回调函数 */


          if (needUpdate && typeof formChange === 'function') formChange(_objectSpread(_objectSpread({}, formData), changeValues));
          if (!formOption.isValueMap && needUpdate) _this.forceUpdate();
        };

        _this.getFieldsValue = function () {
          var onlyValidField = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
          var _this$props$formValue = _this.props.formValue,
              formValue = _this$props$formValue === void 0 ? {} : _this$props$formValue;
          var formData = {};

          _lodash.default.forEach(_this.fields, function (field, name) {
            if (formOption.isValueMap) {
              formData[name] = formValue[name];
            } else {
              formData[name] = field.value;
            }
          });

          return formData;
        };

        _this.getFieldInfo = function (fieldName) {
          var _this$props$formValue2 = _this.props.formValue,
              formValue = _this$props$formValue2 === void 0 ? {} : _this$props$formValue2;
          var result = {
            code: '',
            value: undefined
          };
          var matchedField = _this.fields[fieldName];

          if (matchedField) {
            result.code = 'success';

            if (formOption.isValueMap) {
              if (formValue.hasOwnProperty(fieldName)) {
                result.value = formValue[fieldName];
              }
            } else if (matchedField) {
              result.value = _this.fields[fieldName].value;
            }

            result.Field = matchedField;
          }

          return result;
        };

        _this.getFormFieldByName = function (name) {
          var matchedFormField = _lodash.default.find(_this.state.formFields, {
            identifier: name
          });

          return matchedFormField ? _lodash.default.cloneDeep(matchedFormField) : null;
        };

        _this.getFieldDecorator = function (name, rule) {
          return function (wrapper, fieldElem) {
            var matchResult = _this.getFieldInfo(name);

            if (matchResult.code !== 'success') return;
            var cloneProps = {
              value: matchResult.value,
              onChange: function onChange(val) {
                _this.setFieldsValue((0, _defineProperty2.default)({}, name, val));
              },
              setDefault: function setDefault(val) {
                _this.setDefaultValues((0, _defineProperty2.default)({}, name, val));
              },
              ref: function ref(_ref3) {
                matchResult.Field.componentInstance = _ref3;
              },
              formReady: _this.state.formReady
            };
            if (_this.validators) _this.validators.addRule(name, rule);

            var cloneFieldElem = /*#__PURE__*/_react.default.cloneElement(fieldElem, cloneProps); // return cloneFieldElem;


            return /*#__PURE__*/_react.default.cloneElement(wrapper, {
              ref: function ref(_ref4) {
                matchResult.Field.fieldWrapper = _ref4;
              }
            }, cloneFieldElem);
          };
        };

        _this.setFieldWatch = function (fieldName, fn, watchId) {
          if (typeof fn === 'function' && fieldName && fieldName in _this.fields) {
            var fieldInstance = _this.fields[fieldName];
            fieldInstance.setWatch(fn, watchId);
          }
        };

        _this.cookForm = function () {
          var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

          /* 
              publicProps:表单级别的公共props每个field都应该接受
              privateProps:字段级别的props，包含所有field的私有props,需要过滤后传入对应的字段组件
              params:用于方法本身的一些逻辑参数
          */
          var publicProps = options.publicProps,
              privateProps = options.privateProps,
              bottomExtra = options.bottomExtra,
              topExtra = options.topExtra;
          var _this$state2 = _this.state,
              formFields = _this$state2.formFields,
              formReady = _this$state2.formReady;
          var fieldMapsPlus = formOption.fieldMapsPlus;
          var FormNode = null,
              Node = null;

          if (!_lodash.default.isEmpty(formFields) && formReady) {
            if (platform === WEB) {
              Node = /*#__PURE__*/_react.default.createElement(_WebFormPie.default, {
                formFields: formFields,
                FormDish: FormDish,
                FormChef: HocFormChef,
                formInstance: _this.instance,
                options: options,
                fieldMapsPlus: fieldMapsPlus
              });
            } else {
              Node = formFields.map(function (field, index) {
                if (field.property.isFieldHide) return null;
                return /*#__PURE__*/_react.default.createElement(FormDish, {
                  FormBuild: HocFormChef,
                  key: field.identifier || index,
                  form: _this.instance,
                  field: field,
                  publicProps: publicProps,
                  privateProps: privateProps,
                  fieldMapsPlus: fieldMapsPlus
                });
              });
            }

            FormNode = /*#__PURE__*/_react.default.createElement("section", {
              className: "mk-form"
            }, topExtra ? topExtra : null, Node, bottomExtra ? bottomExtra : null);
          } else {
            FormNode = /*#__PURE__*/_react.default.createElement(_FormTombStone.default, {
              platform: platform
            });
          }

          ;
          return FormNode;
        };

        _this.formInstantiate = /*#__PURE__*/function () {
          var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(orgFormFields) {
            var options,
                formMode,
                formFields,
                preDefinedFormulas,
                _args = arguments;
            return _regenerator.default.wrap(function _callee$(_context) {
              while (1) {
                switch (_context.prev = _context.next) {
                  case 0:
                    options = _args.length > 1 && _args[1] !== undefined ? _args[1] : {
                      preDefinedFormulas: []
                    };

                    if (!(!orgFormFields && _lodash.default.isEmpty(orgFormFields))) {
                      _context.next = 3;
                      break;
                    }

                    return _context.abrupt("return");

                  case 3:
                    _this.debugConsole('Start FormInstantiate');

                    _this.debugConsole('Instantiate options = ', options);

                    formMode = _this.state.formMode;
                    formFields = (0, _toConsumableArray2.default)(orgFormFields);

                    _this.debugConsole('FormFields = ', formFields);

                    _context.next = 10;
                    return new Promise(function (resolve, reject) {
                      _this.setState({
                        formFields: formFields
                      }, function () {
                        resolve();
                      });
                    });

                  case 10:
                    _this.debugConsole('FormInstantiate step1-generateValidator');

                    _this.validators = (0, _generateValidator.default)(formFields, formOption.cookerOption.validateMessages);

                    _this.debugConsole('FormInstantiate step2-fieldInstantiate');

                    _this.fieldInstantiate(formFields); //只有在编辑的状态下，才需要公式和联动（如有特殊逻辑，在项目代码手动触发修改，不能把特殊代码写入通用核心代码中）


                    if (formMode === 'EDIT') {
                      preDefinedFormulas = [].concat((0, _toConsumableArray2.default)(formOption.preDefinedFormulas || []), (0, _toConsumableArray2.default)(options.preDefinedFormulas || []));

                      _this.debugConsole('FormInstantiate step3-buildFormulaParser(if form is editable)');

                      _this.buildFormulaParser(formFields, preDefinedFormulas);
                    }

                    _this.debugConsole('End FormInstantiate');

                  case 16:
                  case "end":
                    return _context.stop();
                }
              }
            }, _callee);
          }));

          return function (_x) {
            return _ref5.apply(this, arguments);
          };
        }();

        _this.initData = function () {
          var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
          var isNew = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
          if (!data) return;

          _this.debugConsole('Start InitData');

          _this.debugConsole('InitData:whether form is brand new?', isNew);

          _this.debugConsole('InitData:data has already is ', data);

          var _this$state3 = _this.state,
              formFields = _this$state3.formFields,
              formMode = _this$state3.formMode;
          var formData = {};

          _lodash.default.forEach(formFields, function (field) {
            if (_lodash.default.has(data, field.identifier)) {
              formData[field.identifier] = data[field.identifier];
            }
          });

          _this.debugConsole('InitData step1-initDynamicFormCtrl');

          _this.initDynamicFormCtrl(formData, formFields);

          _this.debugConsole('InitData step3-set value for form data');

          _this.modifyFormData(formData, false);

          _this.debugConsole('InitData step4-set value for form data');

          _this.formChefParser.updatePoolInFormula(formData);

          _this.debugConsole('InitData step5-set form status is ready');

          _this.setFormReady(true);

          _this.formPorfile.isNew = isNew;

          if (isNew && formMode === 'EDIT') {
            //默认值的获取方式有些是要通过后台去请求，所以默认值的步骤独立出去
            _this.debugConsole('InitData step6-set form default value(if form is editable)');

            _this.formDefaultProcess(formFields);
          }

          _this.debugConsole('End InitData');
        };

        _this.initDynamicFormCtrl = function (formData, formFields) {
          var isFieldHasCondition = false;

          _lodash.default.forEach(formFields, function (field) {
            if (!_lodash.default.isEmpty(field.conditions)) {
              isFieldHasCondition = true;
            }
          });

          if (isFieldHasCondition) {
            var _formFields = _this.dynamicFormCtrl.init(formFields, formData);

            _this.fieldChangeOnCondition(formData, formData, _formFields, true);
          }
        };

        _this.fieldChangeOnCondition = function (formData, changedFields, _formFields, isFirstUpdate) {
          var formFields = _this.state.formFields;

          _this.debugConsole('Start Field Codition');

          _this.debugConsole('Field Codition:pass FormFields are ', _formFields || formFields);

          if (_this.dynamicFormCtrl && _this.dynamicFormCtrl.hasCondition) {
            var fieldOptions = {
              formFields: _formFields || formFields,
              formData: formData,
              changedFields: changedFields,
              isFirstUpdate: isFirstUpdate
            };

            _this.debugConsole('Field Codition:run condition');

            _this.dynamicFormCtrl.onNewFieldChange(fieldOptions).then(function (resp) {
              _this.debugConsole('Field Codition:condition detect result is ', resp.code);

              if (resp.code === 'SHOULD_CHANGE') {
                _this.debugConsole('Field Codition:formField partial update are ', resp.formFields);

                _this.updateFormFields(resp.formFields, isFirstUpdate);
              }
            }, function () {});
          }
        };

        _this.buildAsyncFieldChain = function (formFields) {
          var formulas = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];

          _lodash.default.forEach(formulas, function (f) {
            var matchedChain = _this.asyncFieldChain[f.targetField] || {
              referenceFields: [],
              fnMaps: {}
            };

            if (f.asyncFn && typeof f.asyncFn === 'function') {
              if (!matchedChain.referenceFields.includes(f.referField)) matchedChain.referenceFields.push(f.referField);
              matchedChain.fnMaps[f.referField] = f.asyncFn;
            }

            _this.asyncFieldChain[f.targetField] = matchedChain;
          });
        };

        _this.triggerFormChain = function (formData) {
          var changeValues = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
          var callback = arguments.length > 2 ? arguments[2] : undefined;
          var fieldChains = _this.totalFieldChains;
          var fieldSideEffect = topologicalOrder(fieldChains, changeValues);

          _this.triggerFieldChain(fieldSideEffect, formData, changeValues, callback);
        };

        _this.triggerAsyncFieldChain = function (formData, callback) {
          _this.triggerFormChain(formData, {
            '$associateDefault$': null
          }, callback);
        };

        _this.triggerFieldChain = function (fieldSideEffect, formData) {
          var changeValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
          var callback = arguments.length > 3 ? arguments[3] : undefined;

          _this.debugConsole('Start TriggerFieldChain');

          _this.debugConsole('TriggerFieldChain:fieldSideEffect = ', fieldSideEffect);

          _this.debugConsole('TriggerFieldChain:formData = ', formData);

          _this.debugConsole('TriggerFieldChain:changeValues = ', changeValues);

          _this.debugConsole('TriggerFieldChain:formChefParser = ', _this.formChefParser);

          var formIndex = _this.props.index;
          var fieldChains = _this.totalFieldChains;

          if (fieldSideEffect && fieldSideEffect.status === 'success') {
            var effectedFormData = _objectSpread({}, changeValues);
            /* 按拓扑次序执行异步函数，每一步内无依赖次序，则通过promise.all处理 */


            _utils.default.asyncForEach(fieldSideEffect.tOrder, /*#__PURE__*/function () {
              var _ref6 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(order) {
                var asyncFnSet;
                return _regenerator.default.wrap(function _callee2$(_context2) {
                  while (1) {
                    switch (_context2.prev = _context2.next) {
                      case 0:
                        asyncFnSet = []; //合并每一步中所有的异步函数

                        _lodash.default.forEach(order, function (orderCell) {
                          var matchedAsyncFieldChain = _this.asyncFieldChain[orderCell.identifier];
                          var matchedsyncFieldChain = _this.formChefParser.formulaSet[orderCell.identifier];

                          if (orderCell.referFields && orderCell.referFields.length > 0) {
                            //判断目标对象是否有依赖，原始触发对象不存在依赖
                            _lodash.default.forEach(orderCell.referFields, function (fieldName) {
                              if (_lodash.default.has(effectedFormData, fieldName)) {
                                //触发字段必定在effectedFormData中，理论上不会出现不存在现象                                    
                                var theReferFieldInfo = fieldChains[orderCell.identifier].referFieldsInfo[fieldName];
                                /* 拼装所有异步请求，放入promise.all处理 */

                                if (theReferFieldInfo.isAsync && matchedAsyncFieldChain && matchedAsyncFieldChain.fnMaps && matchedAsyncFieldChain.fnMaps[fieldName]) {
                                  asyncFnSet.push( //构建this.asyncFieldChain的时候已经保证了fnMaps中必然是异步函数
                                  matchedAsyncFieldChain.fnMaps[fieldName](_objectSpread(_objectSpread({}, formData), effectedFormData), {
                                    name: fieldName,
                                    value: effectedFormData[fieldName]
                                  }, {
                                    formIndex: formIndex,
                                    formFields: _this.state.formFields
                                  }).then(function (result) {
                                    if (result && result.status === 'success' && 'data' in result) {
                                      effectedFormData = _objectSpread(_objectSpread({}, effectedFormData), {}, (0, _defineProperty2.default)({}, orderCell.identifier, result.data));
                                    }
                                  }));
                                }
                                /* 同步的联动 */


                                if (!theReferFieldInfo.isAsync && matchedsyncFieldChain) {
                                  var formulaResult = _this.formChefParser.runFormula({
                                    targetField: orderCell.identifier,
                                    referVarName: fieldName,
                                    referVarValue: effectedFormData[fieldName]
                                  });

                                  effectedFormData = _objectSpread(_objectSpread({}, effectedFormData), formulaResult);
                                }
                              }
                            });
                          }
                        });

                        return _context2.abrupt("return", Promise.all(asyncFnSet));

                      case 3:
                      case "end":
                        return _context2.stop();
                    }
                  }
                }, _callee2);
              }));

              return function (_x2) {
                return _ref6.apply(this, arguments);
              };
            }()).finally(function () {
              if (typeof callback === 'function') {
                callback(effectedFormData);
              }
            });
          }
        };

        _this.buildFormulaParser = function (formFields) {
          var preDefinedFormulas = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
          var syncFormulas = [],
              asyncFormulas = [];

          _this.debugConsole('Start BuildFormulaParser');

          _lodash.default.forEach(preDefinedFormulas, function (f) {
            if (f.asyncFn && typeof f.asyncFn === 'function') {
              asyncFormulas.push(f);
            } else {
              syncFormulas.push(f);
            }
          });

          _this.debugConsole('BuildFormulaParser:syncFormulas = ', syncFormulas);

          _this.debugConsole('BuildFormulaParser:asyncFormulas = ', asyncFormulas);

          _this.formChefParser.buildFormFormula(formFields, syncFormulas);

          if (asyncFormulas.length > 0) _this.buildAsyncFieldChain(formFields, asyncFormulas);
          var syncFormulaSet = _this.formChefParser.formulaSet;
          var asyncFormulaSet = _this.asyncFieldChain;
          /* 合并同步和异步的联动数据集合 */

          var syncTargets = Object.keys(syncFormulaSet);
          var asyncTargets = Object.keys(asyncFormulaSet);

          var totalTargets = _lodash.default.union(syncTargets, asyncTargets);

          var fieldChains = {};

          _lodash.default.forEach(totalTargets, function (tname) {
            //根据新生成的totalTargets来构建全部联动信息
            var syncReferFields = _lodash.default.has(syncFormulaSet, tname) ? syncFormulaSet[tname].referenceFields : [];
            var asyncReferFields = _lodash.default.has(asyncFormulaSet, tname) ? asyncFormulaSet[tname].referenceFields : [];

            var totoalReferenceFields = _lodash.default.union(syncReferFields, asyncReferFields);

            var referFieldsInfo = {};

            _lodash.default.forEach(totoalReferenceFields, function (rname) {
              referFieldsInfo[rname] = {};

              if (asyncReferFields.includes(rname)) {
                referFieldsInfo[rname].isAsync = true;
              } else {
                referFieldsInfo[rname].isAsync = false;
              }
            });

            fieldChains[tname] = {
              referenceFields: totoalReferenceFields,
              referFieldsInfo: referFieldsInfo
            };
          });

          _this.totalFieldChains = fieldChains;

          _this.debugConsole('BuildFormulaParser:totalFieldChains = ', _this.totalFieldChains);
        };

        _this.formDefaultProcess = function () {
          var formFields = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];

          /* 同步的默认值设置 */
          var fieldsValue = {};

          _lodash.default.forEach(formFields, function (field) {
            var fieldInstance = _this.fields[field.identifier];

            if (fieldInstance) {
              var v = fieldInstance.getDefault();

              if (v && v.then && typeof v.then === 'function') {
                v.then(function (r) {
                  if (r && r.hasDefault && r.value !== undefined) {
                    _this.setDefaultValues((0, _defineProperty2.default)({}, field.identifier, r.value));
                  }
                });
              } else if (v && v.hasDefault) {
                fieldsValue[field.identifier] = v.value;
              }
            }
          });

          _this.setDefaultValues(fieldsValue);
          /* 异步的默认值设置 */


          var currentFormData = _this.getFieldsValue();

          _this.triggerAsyncFieldChain(currentFormData, function (effectedFormData) {
            var nextChangeValues = {};

            _lodash.default.forEach(effectedFormData, function (v, k) {
              if (k !== '$associateDefault$') nextChangeValues[k] = v;
            });
            /* NOTE  triggerAsyncFieldChain已经触发了formchef中定义的所有的联动规则*/


            _this.modifyFormData(nextChangeValues);
            /* NOTE 手动触发watch观察函数,用于解决默认值无法触发watch的问题 */


            _lodash.default.forEach(nextChangeValues, function (value, key) {
              if (key in _this.fields) {
                var fieldInstance = _this.fields[key];

                _lodash.default.forEach(fieldInstance.watch, function (item) {
                  if (typeof item === 'function') {
                    item(value, _objectSpread(_objectSpread({}, currentFormData), nextChangeValues));
                  }
                });
              }
            });
          });
        };

        _this.setDefaultValues = function () {
          var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
          if (!_this.formPorfile.isNew) return;
          var fieldsValue = {};

          _lodash.default.forEach(data, function (val, key) {
            var fieldValue = _this.getFieldValue(key);

            if (fieldValue === undefined) fieldsValue[key] = val;
          });

          if (!_lodash.default.isEmpty(fieldsValue)) _this.setFieldsValue(fieldsValue, {
            blockValidate: true
          });
        };

        _this.fieldInstantiate = function () {
          var formFields = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
          _this.fields = {};

          _lodash.default.forEach(formFields, function (field) {
            var defaultHandle = _this.defaultFnObj[field.identifier];
            var fieldInstance = new _Field.default({
              config: field,
              defaultHandle: defaultHandle
            });
            fieldInstance.setValidator(_this.validators);
            _this.fields[field.identifier] = fieldInstance;
          });
        };

        _this.updateFieldInstance = function (partialFields) {
          _lodash.default.forEach(partialFields, function (field) {
            if (_this.fields[field.identifier]) {
              _this.fields[field.identifier].updateConfig(field);
            }
          });

          _this.validators = (0, _generateValidator.default)(_this.state.formFields, formOption.cookerOption.validateMessages);
        };

        _this.clearValidateError = function (name) {
          var shouldUpdate = false;

          if (_this.fields[name] && _this.fields[name].validateError) {
            shouldUpdate = true;
            _this.fields[name].validateError = undefined;
          }

          if (shouldUpdate) {
            _this.forceUpdate();
          }
        };

        _this.validateField = function (name, val) {
          _this.validators.validate((0, _defineProperty2.default)({}, name, val), {
            formFields: _this.state.formFields,
            fieldInstances: _this.fields
          }, function (errors, fields) {
            var shouldUpdate = false;

            if (errors) {
              _lodash.default.forEach(errors, function (err) {
                var message = err.message,
                    field = err.field;

                if (_this.fields[field] && _this.fields[field].validateError !== message) {
                  shouldUpdate = true;
                  _this.fields[field].validateError = message;
                }
              });
            } else if (_this.fields[name].validateError) {
              shouldUpdate = true;
              _this.fields[name].validateError = undefined;
            }

            if (shouldUpdate) {
              _this.forceUpdate();
            }
          });
        };

        _this.validateFields = function (first, second) {
          var fieldIds, cb;

          if (typeof first === 'function') {
            cb = first;
          }

          if (_lodash.default.isArray(first)) {
            fieldIds = first;

            if (typeof second === 'function') {
              cb = second;
            }
          }

          var formData = _this.getFieldsValue();

          var firstField;

          _this.debugConsole('ValidateFields Start');

          _this.debugConsole('The form data are', formData);

          _this.debugConsole('The form field is', _this.state.formFields);

          var validFormData = {};

          _lodash.default.forEach(formData, function (v, k) {
            var matchedField = _lodash.default.find(_this.state.formFields, {
              identifier: k
            });

            if (matchedField && !matchedField.property.isFieldHide) {
              if (fieldIds) {
                if (fieldIds.includes(k)) validFormData[k] = v;
              } else {
                validFormData[k] = v;
              }
            }
          });

          if (fieldIds) {
            _this.debugConsole('The validation has partial field keys,they are', fieldIds);
          }

          _this.debugConsole('The valid form data are', validFormData);

          _this.validators.validate(validFormData, {
            formFields: _this.state.formFields,
            fieldInstances: _this.fields
          }, function (errors, fields) {
            _this.debugConsole('Form Validation result are', errors, fields);

            if (_lodash.default.filter(errors, function (o) {
              return o.message !== '';
            }).length === 0) {
              errors = undefined;
            } else {
              errors = _lodash.default.filter(errors, function (o) {
                return o.message !== '';
              });
            }

            _lodash.default.forEach(_this.fields, function (field) {
              field.validateError = undefined;
            });

            if (errors) {
              _lodash.default.forEach(errors, function (err) {
                var message = err.message,
                    field = err.field;

                if (_this.fields[field]) {
                  _this.fields[field].validateError = message;
                  if (!firstField) firstField = _this.fields[field];
                }
              });
            }

            if (typeof cb === 'function') cb(errors, formData);

            _this.forceUpdate();

            if (firstField) firstField.scroll();
          });

          _this.debugConsole('ValidateFields End');
        };

        _this.rebuildForm = /*#__PURE__*/function () {
          var _ref7 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(formFields, options) {
            var prevFormData;
            return _regenerator.default.wrap(function _callee3$(_context3) {
              while (1) {
                switch (_context3.prev = _context3.next) {
                  case 0:
                    prevFormData = _this.getFieldsValue();
                    _context3.next = 3;
                    return _this.reset();

                  case 3:
                    _context3.next = 5;
                    return _this.formInstantiate(formFields, options);

                  case 5:
                    _this.initData(prevFormData, true);

                  case 6:
                  case "end":
                    return _context3.stop();
                }
              }
            }, _callee3);
          }));

          return function (_x3, _x4) {
            return _ref7.apply(this, arguments);
          };
        }();

        _this.reset = function () {
          _this.fields = {};
          _this.validators = undefined;
          return new Promise(function (resolve) {
            _this.asyncFieldChain = {};
            _this.fields = {};

            _this.setState({
              formReady: false // formFields: [],

            }, function () {
              resolve();
            });
          });
        };

        _this.forwardRef = function (ref) {
          _this.wrappedRef = ref;
        };

        _this.state = {
          formReady: formOption.formReadyLock ? false : true,
          formFields: [],
          formMode: props.formMode ? props.formMode : 'EDIT'
        };
        _this.fields = {};
        _this.defaultFnObj = {};
        _this.validators = undefined;
        _this.dynamicFormCtrl = new _FormChefCommon.default.DynamicFormCtrl({
          updateFormFields: _this.updateFormFields
        });
        _this.formChefParser = new _FormChefCommon.default.formChefParser();
        _this.FormTombStone = platform === WEB ? _FormTombStone.WebTombStone : _FormTombStone.TombStone;
        _this.asyncFieldChain = {};
        _this.totalFieldChains = {};
        _this.instance = {
          initData: _this.initData,
          cookForm: _this.cookForm,
          formInstantiate: _this.formInstantiate,
          setWatch: _this.setFieldWatch,
          setFieldsValue: _this.setFieldsValue,
          getFieldDecorator: _this.getFieldDecorator,
          getFieldError: _this.getFieldError,
          validateFields: _this.validateFields,
          clearValidateError: _this.clearValidateError,
          rebuildForm: _this.rebuildForm,
          getFieldValue: _this.getFieldValue,
          getFieldsValue: _this.getFieldsValue,
          setDefaultFn: function setDefaultFn(defaultFnObj) {
            return _this.defaultFnObj = defaultFnObj;
          },
          // 在 formInstantiate 之前调用
          getFormFieldByName: _this.getFormFieldByName,
          updateFormFields: _this.updateFormFields,
          reset: _this.reset
        };
        _this.formPorfile = {
          isNew: false
        };

        _this.debugConsole('formchef under debug mode');

        return _this;
      }

      (0, _createClass2.default)(WrapperFormChef, [{
        key: "render",
        value: function render() {
          var _this$state4 = this.state,
              formReady = _this$state4.formReady,
              formFields = _this$state4.formFields;
          return /*#__PURE__*/_react.default.createElement(WrappedComponent, (0, _extends2.default)({}, this.props, {
            FormBuild: FormChef,
            FormDish: formReady ? FormDish : this.FormTombStone,
            formState: {
              formReady: formReady,
              formFields: formFields
            },
            form: this.instance,
            ref: this.forwardRef
          }));
        }
      }]);
      return WrapperFormChef;
    }(_react.Component);

    return WrapperFormChef;
  };
};

HocFormChef.defineDish = defineDish;
HocFormChef.definePlatform = definePlatform;
HocFormChef.setOriginalRule = _Field.setOriginalRule;
/**
 * @author 卫蓉，刀马
 */

function FormChef() {
  return /*#__PURE__*/_react.default.createElement("div", null);
}

var _default = HocFormChef;
exports.default = _default;