import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _get from "@babel/runtime/helpers/get";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/inherits";
import _createSuper from "@babel/runtime/helpers/createSuper";
import _regeneratorRuntime from "@babel/runtime/regenerator";
import { __decorate } from "tslib";
import React, { cloneElement, isValidElement } from 'react';
import { action, computed, isArrayLike, observable, runInAction, toJS } from 'mobx';
import classNames from 'classnames';
import isPromise from 'is-promise';
import isNumber from 'lodash/isNumber';
import isNil from 'lodash/isNil';
import isLdEmpty from 'lodash/isEmpty';
import isObject from 'lodash/isObject';
import defaultTo from 'lodash/defaultTo';
import uniqWith from 'lodash/uniqWith';
import isFunction from 'lodash/isFunction';
import findLastIndex from 'lodash/findLastIndex';
import { observer } from 'mobx-react';
import noop from 'lodash/noop';
import KeyCode from '../../../es/_util/KeyCode';
import warning from '../../../es/_util/warning';
import { pxToRem } from '../../../es/_util/UnitConvertor';
import { Tooltip as TextTooltip } from '../core/enum';
import autobind from '../_util/autobind';
import Validator from '../validator/Validator';
import Validity from '../validator/Validity';
import FormContext from '../form/FormContext';
import DataSetComponent from '../data-set/DataSetComponent';
import isEmpty from '../_util/isEmpty';
import { FieldTrim, FieldType } from '../data-set/enum';
import { ShowHelp } from './enum';
import { FIELD_SUFFIX } from '../form/utils';
import { LabelLayout, ShowValidation } from '../form/enum';
import Animate from '../animate';
import { defaultRenderer as _defaultRenderer, fromRangeValue, getDateFormatByField, getValueKey as _getValueKey, isFieldValueEmpty, processValue as _processValue, renderMultipleValues as _renderMultipleValues, renderRangeValue as _renderRangeValue, renderValidationMessage, showValidationMessage as _showValidationMessage, toMultipleValue, toRangeValue, transformHighlightProps } from './utils';
import isSame from '../_util/isSame';
import formatString from '../formatter/formatString';
import { hide, show } from '../tooltip/singleton';
import isOverflow from '../overflow-tip/util';
var map = {};
export function getFieldsById(id) {
  if (!map[id]) {
    map[id] = [];
  }

  return map[id];
}
export var FormField = /*#__PURE__*/function (_DataSetComponent) {
  _inherits(FormField, _DataSetComponent);

  var _super = _createSuper(FormField);

  function FormField() {
    var _this;

    _classCallCheck(this, FormField);

    _this = _super.apply(this, arguments);
    _this.emptyValue = null; // 多选中出现了校验值的数量大于一那么输入框不需要存在校验信息展示

    _this.multipleValidateMessageLength = 0;
    return _this;
  }

  _createClass(FormField, [{
    key: "name",
    get: function get() {
      return this.observableProps.name;
    }
  }, {
    key: "value",
    get: function get() {
      return this.observableProps.value;
    },
    set: function set(value) {
      var _this2 = this;

      runInAction(function () {
        _this2.observableProps.value = value;
      });
    }
  }, {
    key: "labelLayout",
    get: function get() {
      return this.props.labelLayout || this.context.labelLayout;
    }
  }, {
    key: "labelTooltip",
    get: function get() {
      return this.props.labelTooltip || this.context.labelTooltip || this.context.getTooltip('label');
    }
  }, {
    key: "hasFloatLabel",
    get: function get() {
      var labelLayout = this.labelLayout;
      return labelLayout === LabelLayout["float"];
    }
  }, {
    key: "isControlled",
    get: function get() {
      return this.getControlled(this.props);
    }
  }, {
    key: "pristine",
    get: function get() {
      return this.observableProps.pristine;
    }
  }, {
    key: "defaultValidationMessages",
    get: function get() {
      return {};
    }
  }, {
    key: "editable",
    get: function get() {
      return this.isEditable();
    }
  }, {
    key: "dataSet",
    get: function get() {
      var record = this.record;

      if (record) {
        return record.dataSet;
      }

      var observableProps = this.observableProps;

      if ('dataSet' in observableProps) {
        return observableProps.dataSet;
      }

      return observableProps.contextDataSet;
    }
  }, {
    key: "record",
    get: function get() {
      var observableProps = this.observableProps;

      if ('record' in observableProps) {
        return observableProps.record;
      }

      var dataSet = observableProps.dataSet,
          dataIndex = observableProps.dataIndex;

      if (dataSet) {
        if (isNumber(dataIndex)) {
          return dataSet.get(dataIndex);
        }

        return dataSet.current;
      }

      if (isNumber(dataIndex)) {
        var contextDataSet = observableProps.contextDataSet;

        if (contextDataSet) {
          return contextDataSet.get(dataIndex);
        }
      }

      return observableProps.contextRecord;
    }
  }, {
    key: "dataIndex",
    get: function get() {
      var _this$observableProps = this.observableProps,
          dataIndex = _this$observableProps.dataIndex,
          contextDataIndex = _this$observableProps.contextDataIndex;
      return defaultTo(dataIndex, contextDataIndex);
    }
  }, {
    key: "field",
    get: function get() {
      var dataSet = this.dataSet,
          name = this.name,
          observableProps = this.observableProps;
      var displayName = this.constructor.displayName;

      if (displayName !== 'Output' && !name) {
        warning(!observableProps.dataSet, "".concat(displayName, " with binding DataSet need property name."));
        warning(!observableProps.record, "".concat(displayName, " with binding Record need property name."));
      }

      if (name) {
        // const recordField = record ? record.getField(name) : undefined;
        // if (recordField) {
        //   return recordField;
        // }
        if (dataSet) {
          return dataSet.getField(name);
        }
      }

      return undefined;
    }
  }, {
    key: "valid",
    get: function get() {
      return this.isValid();
    }
  }, {
    key: "multiple",
    get: function get() {
      return this.getProp('multiple');
    }
    /**
     * 获取字段货币属性
     */

  }, {
    key: "currency",
    get: function get() {
      return this.getProp('currency');
    }
  }, {
    key: "trim",
    get: function get() {
      return this.getProp('trim');
    }
  }, {
    key: "format",
    get: function get() {
      return this.getProp('format');
    }
  }, {
    key: "range",
    get: function get() {
      var field = this.field,
          observableProps = this.observableProps,
          record = this.record;

      if (field) {
        return field && field.get('range', record);
      }

      return 'range' in observableProps ? observableProps('range') : this.props.range;
    }
  }, {
    key: "readOnly",
    get: function get() {
      return this.isReadOnly();
    }
  }, {
    key: "highlight",
    get: function get() {
      return this.getDisplayProp('highlight');
    }
  }, {
    key: "showValidation",
    get: function get() {
      var _this$observableProps2 = this.observableProps.showValidation,
          showValidation = _this$observableProps2 === void 0 ? this.getContextConfig('showValidation') : _this$observableProps2;
      return showValidation;
    }
  }, {
    key: "showHelp",
    get: function get() {
      var _this$observableProps3 = this.observableProps.showHelp,
          showHelp = _this$observableProps3 === void 0 ? this.getContextConfig('showHelp') : _this$observableProps3;
      return showHelp;
    }
  }, {
    key: "helpTooltipProps",
    get: function get() {
      var helpTooltipProps = this.observableProps.helpTooltipProps;
      return helpTooltipProps;
    }
  }, {
    key: "highlightRenderer",
    get: function get() {
      var _this$observableProps4 = this.observableProps.highlightRenderer,
          highlightRenderer = _this$observableProps4 === void 0 ? this.getContextConfig('highlightRenderer') : _this$observableProps4;
      return highlightRenderer;
    }
  }, {
    key: "getControlled",
    value: function getControlled(props) {
      return props.value !== undefined;
    }
  }, {
    key: "defaultRenderer",
    value: function defaultRenderer(renderProps) {
      return _defaultRenderer(renderProps);
    }
    /**
     * 判断是否应该显示验证信息, 作为属性传给Tooltip
     *
     * @readonly
     * @type {(undefined | boolean)}
     * @memberof FormField
     */

  }, {
    key: "isValidationMessageHidden",
    value: function isValidationMessageHidden(message) {
      var _this$props = this.props,
          hidden = _this$props.hidden,
          noValidate = _this$props.noValidate;
      return !!(hidden || !message || this.pristine || !this.record && noValidate);
    }
  }, {
    key: "showValidationMessage",
    value: function showValidationMessage(e, message) {
      _showValidationMessage(e, message, this.context.getTooltipTheme('validation'), this.context.getTooltipPlacement('validation'), this.getContextConfig);
    }
  }, {
    key: "isEmpty",
    value: function isEmpty() {
      var value = this.getValue();
      return isFieldValueEmpty(value, this.range, this.multiple);
    }
  }, {
    key: "isValid",
    value: function isValid() {
      if (this.pristine) {
        return true;
      }

      var field = this.field;

      if (field) {
        return field.isValid(this.record);
      }

      var validationResults = this.validationResults;

      if (validationResults) {
        return !validationResults.length;
      }

      return true;
    }
  }, {
    key: "isReadOnly",
    value: function isReadOnly() {
      var readOnly = this.observableProps.readOnly;

      if (readOnly || this.pristine) {
        return true;
      }

      var field = this.field;
      return field ? field.get('readOnly', this.record) : false;
    }
  }, {
    key: "isEditable",
    value: function isEditable() {
      return !this.disabled && !this.readOnly;
    }
  }, {
    key: "isEditableLike",
    value: function isEditableLike() {
      return false;
    }
  }, {
    key: "getObservablePropsExcludeOutput",
    value: function getObservablePropsExcludeOutput(props, context) {
      return {
        readOnly: context.readOnly || props.readOnly || this.getControlled(props) && !props.onChange && !props.onInput
      };
    }
  }, {
    key: "getObservableProps",
    value: function getObservableProps(props, context) {
      var observableProps = _objectSpread(_objectSpread(_objectSpread({}, _get(_getPrototypeOf(FormField.prototype), "getObservableProps", this).call(this, props, context)), this.getObservablePropsExcludeOutput(props, context)), {}, {
        label: props.label,
        name: props.name,
        contextDataSet: context.dataSet,
        contextRecord: context.record,
        dataIndex: props.dataIndex,
        contextDataIndex: context.dataIndex,
        value: 'value' in props ? props.value : this.observableProps ? this.observableProps.value : props.defaultValue,
        disabled: context.disabled || props.disabled,
        pristine: context.pristine || props.pristine,
        highlight: props.highlight,
        highlightRenderer: 'highlightRenderer' in props ? props.highlightRenderer : context.fieldHighlightRenderer,
        showValidation: 'showValidation' in props ? props.showValidation : context.showValidation,
        showHelp: 'showHelp' in props ? props.showHelp : context.showHelp,
        helpTooltipProps: props.helpTooltipProps
      });

      if ('record' in props) {
        observableProps.record = props.record;
      }

      return observableProps;
    }
  }, {
    key: "getOmitPropsKeys",
    value: function getOmitPropsKeys() {
      return _get(_getPrototypeOf(FormField.prototype), "getOmitPropsKeys", this).call(this).concat(['record', 'defaultValue', 'dataIndex', 'onEnterDown', 'onClear', 'onBeforeChange', 'readOnly', 'validator', 'validationRenderer', 'help', 'showHelp', 'helpTooltipProps', 'renderer', 'maxTagPlaceholder', 'maxTagCount', 'maxTagTextLength', 'rowIndex', 'colIndex', 'labelLayout', '_inTable', 'labelWidth', 'pristine', 'range', 'trim', 'newLine', 'fieldClassName', 'preventRenderer', 'highlight', 'highlightRenderer', 'labelTooltip', 'isFlat', 'useColon', 'requiredMarkAlign', 'showValidation', 'tagRenderer']);
    }
  }, {
    key: "getOtherPropsExcludeOutput",
    value: function getOtherPropsExcludeOutput(otherProps) {
      otherProps.onChange = !this.disabled && !this.readOnly ? this.handleChange : noop;
      otherProps.onKeyDown = this.handleKeyDown;
      otherProps.onCompositionStart = this.handleCompositionStart;
      otherProps.onCompositionEnd = this.handleChange;
      return otherProps;
    }
  }, {
    key: "getOtherProps",
    value: function getOtherProps() {
      var otherProps = _get(_getPrototypeOf(FormField.prototype), "getOtherProps", this).call(this);

      otherProps.onMouseEnter = this.handleMouseEnter;
      otherProps.onMouseLeave = this.handleMouseLeave;
      return this.getOtherPropsExcludeOutput(otherProps);
    }
  }, {
    key: "getWrapperClassNamesExcludeOutput",
    value: function getWrapperClassNamesExcludeOutput(prefixCls, empty) {
      var _ref;

      return _ref = {}, _defineProperty(_ref, "".concat(prefixCls, "-empty"), empty), _defineProperty(_ref, "".concat(prefixCls, "-readonly"), this.readOnly), _ref;
    }
  }, {
    key: "getWrapperClassNames",
    value: function getWrapperClassNames() {
      var _get2, _ref2;

      var prefixCls = this.prefixCls;
      var required = this.getProp('required');
      var empty = this.isEmpty();

      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }

      return (_get2 = _get(_getPrototypeOf(FormField.prototype), "getWrapperClassNames", this)).call.apply(_get2, [this, (_ref2 = {}, _defineProperty(_ref2, "".concat(prefixCls, "-highlight"), this.highlight), _defineProperty(_ref2, "".concat(prefixCls, "-invalid"), !this.valid), _defineProperty(_ref2, "".concat(prefixCls, "-float-label"), this.hasFloatLabel), _defineProperty(_ref2, "".concat(prefixCls, "-required"), required), _defineProperty(_ref2, "".concat(prefixCls, "-required-colors"), required && (empty || !this.getContextConfig('showRequiredColorsOnlyEmpty'))), _ref2), this.getWrapperClassNamesExcludeOutput(prefixCls, empty)].concat(args));
    }
  }, {
    key: "renderWrapper",
    value: function renderWrapper() {
      return undefined;
    }
  }, {
    key: "renderHelpMessage",
    value: function renderHelpMessage() {
      var showHelp = this.showHelp;

      if (showHelp === ShowHelp.newLine) {
        var help = this.getDisplayProp('help');

        if (help) {
          return /*#__PURE__*/React.createElement("div", {
            key: "help",
            className: "".concat(this.getContextProPrefixCls(FIELD_SUFFIX), "-help")
          }, help);
        }
      }
    }
  }, {
    key: "getLabel",
    value: function getLabel() {
      return toJS(this.getProp('label'));
    }
  }, {
    key: "renderFloatLabel",
    value: function renderFloatLabel() {
      if (this.hasFloatLabel) {
        var label = this.getLabel();

        if (label) {
          var _classNames;

          var floatLabelOffsetX = this.floatLabelOffsetX;
          var prefixCls = this.getContextProPrefixCls(FIELD_SUFFIX);
          var required = this.getProp('required');
          var classString = classNames("".concat(prefixCls, "-label"), (_classNames = {}, _defineProperty(_classNames, "".concat(prefixCls, "-required"), required), _defineProperty(_classNames, "".concat(prefixCls, "-readonly"), this.readOnly), _classNames));
          var style = floatLabelOffsetX ? {
            marginLeft: pxToRem(floatLabelOffsetX, true)
          } : undefined;
          return /*#__PURE__*/React.createElement("div", {
            className: "".concat(prefixCls, "-label-wrapper"),
            style: style
          }, /*#__PURE__*/React.createElement("div", {
            className: classString,
            onMouseEnter: this.handleFloatLabelMouseEnter,
            onMouseLeave: this.handleFloatLabelMouseLeave
          }, label));
        }
      }
    }
  }, {
    key: "componentDidMount",
    value: function componentDidMount() {
      _get(_getPrototypeOf(FormField.prototype), "componentDidMount", this).call(this);

      this.addToForm(this.props, this.context);
    }
  }, {
    key: "componentWillReceiveProps",
    value: function componentWillReceiveProps(nextProps, nextContext) {
      _get(_getPrototypeOf(FormField.prototype), "componentWillReceiveProps", this).call(this, nextProps, nextContext);

      this.removeFromForm(this.props, this.context);
      this.addToForm(nextProps, nextContext);

      if (!this.record && this.props.value !== nextProps.value) {
        this.validate(nextProps.value);
      }
    }
  }, {
    key: "componentWillUnmount",
    value: function componentWillUnmount() {
      this.removeFromForm(this.props, this.context);

      if (this.tooltipShown) {
        hide();
        this.tooltipShown = false;
      }
    }
  }, {
    key: "addToForm",
    value: function addToForm(props, context) {
      var form = props.form;
      var formNode = context.formNode;

      if (form) {
        var fields = map[form];

        if (!fields) {
          fields = [];
          map[form] = fields;
        }

        fields.push(this);
      } else if (formNode) {
        formNode.addField(this);
      }
    }
  }, {
    key: "removeFromForm",
    value: function removeFromForm(props, context) {
      var form = props.form;
      var formNode = context.formNode;

      if (form) {
        var fields = map[form];

        if (fields) {
          var index = fields.indexOf(this);

          if (index !== -1) {
            fields.splice(index, 1);
          }
        }
      } else if (formNode) {
        formNode.removeField(this);
      }
    }
  }, {
    key: "renderValidationResult",
    value: function renderValidationResult(validationResult) {
      var validationMessage = this.getValidationMessage(validationResult);
      var _this$context = this.context,
          labelLayout = _this$context.labelLayout,
          getProPrefixCls = _this$context.getProPrefixCls;

      if (validationMessage) {
        var showIcon = !(labelLayout === LabelLayout["float"] || this.showValidation === ShowValidation.newLine);
        return renderValidationMessage(validationMessage, showIcon, getProPrefixCls);
      }
    }
  }, {
    key: "getValidatorProp",
    value: function getValidatorProp(key) {
      switch (key) {
        case 'type':
          return this.getFieldType();

        case 'customValidator':
          return this.getProp('validator');

        case 'range':
          return this.range;

        case 'multiple':
          return this.multiple;

        case 'defaultValidationMessages':
          return _objectSpread(_objectSpread({}, this.defaultValidationMessages), this.getContextConfig('defaultValidationMessages'));

        default:
          return this.getProp(key);
      }
    }
  }, {
    key: "getValidatorProps",
    value: function getValidatorProps() {
      var name = this.name;
      return {
        name: name,
        form: this.context.formNode
      };
    }
  }, {
    key: "getValidationResults",
    value: function getValidationResults() {
      var field = this.field,
          record = this.record;

      if (field) {
        return field.getValidationErrorValues(record);
      }

      return this.validationResults;
    }
  }, {
    key: "getValidationMessage",
    value: function getValidationMessage(validationResult) {
      if (validationResult === undefined) {
        var results = this.getValidationResults();

        if (results && results.length) {
          validationResult = results[0];
        }
      }

      var validationRenderer = this.props.validationRenderer;

      if (validationResult) {
        if (validationRenderer) {
          var validationMessage = validationRenderer(validationResult, validationResult.validationProps);

          if (validationMessage) {
            return validationMessage;
          }
        }

        return validationResult.validationMessage;
      }
    }
  }, {
    key: "showTooltip",
    value: function showTooltip(e) {
      if (!this.hasFloatLabel && this.showValidation === ShowValidation.tooltip) {
        var message = this.getTooltipValidationMessage();

        if (message) {
          _showValidationMessage(e, message, this.context.getTooltipTheme('validation'), this.context.getTooltipPlacement('validation'), this.getContextConfig);

          return true;
        }
      }

      return false;
    }
  }, {
    key: "handleMouseEnter",
    value: function handleMouseEnter(e) {
      if (this.showTooltip(e)) {
        this.tooltipShown = true;
      }

      var _this$props$onMouseEn = this.props.onMouseEnter,
          onMouseEnter = _this$props$onMouseEn === void 0 ? noop : _this$props$onMouseEn;
      onMouseEnter(e);
    }
  }, {
    key: "handleMouseLeave",
    value: function handleMouseLeave(e) {
      if (this.tooltipShown) {
        hide();
        this.tooltipShown = false;
      }

      var _this$props$onMouseLe = this.props.onMouseLeave,
          onMouseLeave = _this$props$onMouseLe === void 0 ? noop : _this$props$onMouseLe;
      onMouseLeave(e);
    }
  }, {
    key: "handleFloatLabelMouseEnter",
    value: function handleFloatLabelMouseEnter(e) {
      var labelTooltip = this.labelTooltip,
          _this$context2 = this.context,
          getTooltipTheme = _this$context2.getTooltipTheme,
          getTooltipPlacement = _this$context2.getTooltipPlacement;
      var currentTarget = e.currentTarget;

      if (labelTooltip === TextTooltip.always || labelTooltip === TextTooltip.overflow && isOverflow(currentTarget)) {
        show(currentTarget, {
          title: this.getLabel(),
          placement: getTooltipPlacement('label'),
          theme: getTooltipTheme('label')
        });
        this.tooltipShown = true;
      } else if (isArrayLike(labelTooltip)) {
        var tooltipType = labelTooltip[0];
        var labelTooltipProps = labelTooltip[1] || {};
        var duration = (labelTooltipProps.mouseEnterDelay || 0.1) * 1000;

        if (tooltipType === TextTooltip.always || tooltipType === TextTooltip.overflow && isOverflow(currentTarget)) {
          show(currentTarget, _objectSpread({
            theme: getTooltipTheme('label'),
            placement: getTooltipPlacement('label'),
            title: labelTooltipProps.title ? labelTooltipProps.title : this.getLabel()
          }, labelTooltipProps), duration);
          this.tooltipShown = true;
        }
      }
    }
  }, {
    key: "handleFloatLabelMouseLeave",
    value: function handleFloatLabelMouseLeave() {
      hide();
    }
  }, {
    key: "handleFocus",
    value: function handleFocus(e) {
      _get(_getPrototypeOf(FormField.prototype), "handleFocus", this).call(this, e);

      if (this.range && !this.rangeValue) {
        this.beginRange();
      }
    }
  }, {
    key: "handleBlur",
    value: function handleBlur(e) {
      _get(_getPrototypeOf(FormField.prototype), "handleBlur", this).call(this, e);

      if (this.range && (this.editable || this.isEditableLike())) {
        this.endRange();
      }
    }
  }, {
    key: "handleCompositionStart",
    value: function handleCompositionStart() {
      this.lock = true;
    }
  }, {
    key: "handleChange",
    value: function handleChange(e) {
      delete this.lock;
      e.preventDefault();
      e.stopPropagation();
    }
  }, {
    key: "handleKeyDown",
    value: function handleKeyDown(e) {
      var _this$props2 = this.props,
          _this$props2$onKeyDow = _this$props2.onKeyDown,
          onKeyDown = _this$props2$onKeyDow === void 0 ? noop : _this$props2$onKeyDow,
          _this$props2$onEnterD = _this$props2.onEnterDown,
          onEnterDown = _this$props2$onEnterD === void 0 ? noop : _this$props2$onEnterD;
      onKeyDown(e);

      if (!e.isDefaultPrevented()) {
        switch (e.keyCode) {
          case KeyCode.ENTER:
            this.handleEnterDown(e);
            onEnterDown(e);
            break;

          case KeyCode.ESC:
            this.blur();
            break;

          default:
        }
      }
    }
  }, {
    key: "handleEnterDown",
    value: function handleEnterDown(e) {
      if (this.multiple) {
        if (this.range) {
          this.endRange();
          e.preventDefault();
        } else {
          var value = e.target.value;

          if (value !== '') {
            this.syncValueOnBlur(value);
            e.preventDefault();
          }
        }
      } else {
        this.blur();
      }
    }
  }, {
    key: "syncValueOnBlur",
    value: function syncValueOnBlur(value) {
      this.prepareSetValue(value);
    }
  }, {
    key: "handleMutipleValueRemove",
    value: function handleMutipleValueRemove(e, value, index) {
      this.removeValue(value, index);
      e.stopPropagation();
    }
  }, {
    key: "getDateFormat",
    value: function getDateFormat() {
      var field = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.field;
      return getDateFormatByField(field, this.getFieldType(field), this.record);
    }
  }, {
    key: "getProcessValueOptions",
    value: function getProcessValueOptions() {
      return {
        dateFormat: this.getDateFormat(),
        showInvalidDate: this.getContextConfig('showInvalidDate')
      };
    }
  }, {
    key: "processValue",
    value: function processValue(value) {
      return _processValue(value, this.getProcessValueOptions());
    }
  }, {
    key: "getDataSetValue",
    value: function getDataSetValue() {
      var record = this.record,
          pristine = this.pristine,
          name = this.name;

      if (record) {
        return pristine ? record.getPristineValue(name) : record.get(name);
      }
    }
  }, {
    key: "getTextNode",
    value: function getTextNode() {
      var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getValue();
      return this.getTextByValue(value);
    }
  }, {
    key: "getTextByValue",
    value: function getTextByValue(value) {
      var preventRenderer = this.props.preventRenderer;
      var text = this.editable && (preventRenderer || this.isFocused) ? this.processValue(value) : this.processRenderer(value);
      return text;
    }
  }, {
    key: "getText",
    value: function getText(value) {
      return this.processValue(value);
    }
  }, {
    key: "processText",
    value: function processText(value) {
      return value;
    }
  }, {
    key: "processRenderer",
    value: function processRenderer(value, repeat) {
      var field = this.field,
          record = this.record,
          dataSet = this.dataSet,
          _this$props3 = this.props,
          _this$props3$renderer = _this$props3.renderer,
          renderer = _this$props3$renderer === void 0 ? this.defaultRenderer : _this$props3$renderer,
          name = _this$props3.name,
          maxTagTextLength = _this$props3.maxTagTextLength;
      var processedValue;

      if (field && (field.getLookup(record) || field.get('options', record) || field.get('lovCode', record))) {
        // Cascader 值集处理
        if (isArrayLike(value)) {
          var isCascader = !field.get('multiple', record) || value.some(function (v) {
            return isArrayLike(v);
          });
          processedValue = value.map(function (v) {
            return field.getText(v, undefined, record);
          }).join(isCascader ? '/' : '、');
        } else {
          processedValue = field.getText(value, undefined, record);
        }
      } // 值集中不存在 再去取直接返回的值


      var text = this.processText(isNil(processedValue) ? this.processValue(value) : processedValue);
      return renderer ? renderer({
        value: value,
        text: text,
        record: record,
        dataSet: dataSet,
        name: name,
        repeat: repeat,
        maxTagTextLength: maxTagTextLength
      }) : text;
    }
  }, {
    key: "processRangeValue",
    value: function processRangeValue(value) {
      if (value === undefined && !this.multiple) {
        value = toRangeValue(this.getValue(), this.range);
      }

      return value || [];
    }
  }, {
    key: "getOldValue",
    value: function getOldValue() {
      return this.getValue();
    }
  }, {
    key: "getValue",
    value: function getValue() {
      var name = this.name;

      if (this.dataSet && name) {
        return this.getDataSetValue();
      }

      return this.value;
    }
  }, {
    key: "getValues",
    value: function getValues() {
      return toMultipleValue(this.getValue(), this.range);
    }
  }, {
    key: "addValue",
    value: function addValue() {
      for (var _len2 = arguments.length, values = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
        values[_key2] = arguments[_key2];
      }

      if (this.multiple) {
        var oldValues = this.getValues();

        if (values.length) {
          var range = this.range;
          this.setValue(uniqWith([].concat(_toConsumableArray(isArrayLike(range) ? oldValues.map(function (v) {
            return fromRangeValue(v, range);
          }) : oldValues), values), this.compare));
        } else if (!oldValues.length) {
          this.setValue(this.emptyValue);
        } else {
          this.validate(oldValues, false);
        }
      } else {
        this.setValue(values.pop());
      }
    }
  }, {
    key: "isLowerRange",
    value: function isLowerRange(_value1, _value2) {
      return false;
    }
  }, {
    key: "exchangeRangeValue",
    value: function exchangeRangeValue(start, end) {
      var rangeValue = this.rangeValue;

      if (rangeValue) {
        rangeValue[0] = end;
        rangeValue[1] = start;
      }
    }
  }, {
    key: "prepareSetValue",
    value: function prepareSetValue() {
      var processV = this.getProp('processValue');
      var range = this.range;

      for (var _len3 = arguments.length, value = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
        value[_key3] = arguments[_key3];
      }

      var values = value.filter(function (item) {
        return isNumber(item) || !isEmpty(item);
      });

      if (range) {
        var rangeTarget = this.rangeTarget,
            rangeValue = this.rangeValue;

        if (rangeTarget !== undefined && rangeValue) {
          var _rangeValue = _slicedToArray(rangeValue, 2),
              start = _rangeValue[0],
              end = _rangeValue[1];

          var newValue = values.pop();

          if (isFunction(processV)) {
            newValue = processV(newValue, rangeTarget);
          }

          rangeValue[rangeTarget] = newValue;

          if (rangeTarget === 0 && (newValue || isNumber(newValue)) && (end || isNumber(end)) && this.isLowerRange(end, newValue)) {
            this.exchangeRangeValue(newValue, end);
          }

          if (rangeTarget === 1 && (newValue || isNumber(newValue)) && (start || isNumber(start)) && this.isLowerRange(newValue, start)) {
            this.exchangeRangeValue(start, newValue);
          }
        }
      } else {
        if (isFunction(processV)) {
          values = values.map(function (v) {
            return processV(v, undefined);
          });
        }

        this.addValue.apply(this, _toConsumableArray(values));
      }
    }
  }, {
    key: "removeValues",
    value: function removeValues(values) {
      var _this3 = this;

      var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
      var repeat;
      var newValues = values.reduce(function (oldValues, value) {
        repeat = 0;

        var valueKey = _this3.getValueKey(value);

        return oldValues.filter(function (v) {
          if (_this3.getValueKey(v) === valueKey) {
            if (index === -1 || repeat === index) {
              _this3.afterRemoveValue(value, repeat++);

              return false;
            }

            repeat++;
          }

          return true;
        });
      }, this.getValues());
      var range = this.range;
      this.setValue(isArrayLike(range) ? newValues.map(function (v) {
        return fromRangeValue(v, range);
      }) : newValues);
    }
  }, {
    key: "removeValue",
    value: function removeValue(value) {
      var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
      this.removeValues([value], index);
    }
  }, {
    key: "removeLastValue",
    value: function removeLastValue() {
      var _this4 = this;

      var values = this.getValues();
      var index = findLastIndex(values, function (value) {
        return !_this4.isMultipleBlockDisabled(value);
      });

      if (index !== -1) {
        var _values$splice = values.splice(index, 1),
            _values$splice2 = _slicedToArray(_values$splice, 1),
            value = _values$splice2[0];

        var range = this.range;
        this.setValue(isArrayLike(range) ? values.map(function (v) {
          return fromRangeValue(v, range);
        }) : values);
        this.afterRemoveValue(fromRangeValue(value, range), -1);
        return value;
      }
    }
  }, {
    key: "afterRemoveValue",
    value: function afterRemoveValue(_value, _repeat) {// noop
    }
  }, {
    key: "beginRange",
    value: function beginRange() {
      this.setRangeTarget(this.rangeTarget || 0);
      this.rangeValue = this.multiple ? [undefined, undefined] : toRangeValue(this.getValue(), this.range);
    }
  }, {
    key: "endRange",
    value: function endRange() {
      if (this.rangeValue) {
        var values = this.rangeValue.slice();
        this.rangeValue = undefined;

        if (!this.multiple || !values.every(isNil)) {
          this.addValue(fromRangeValue(values, this.range));
        }
      }

      this.setRangeTarget(undefined);
    }
  }, {
    key: "setRangeTarget",
    value: function setRangeTarget(target) {
      this.rangeTarget = target;
    }
  }, {
    key: "compare",
    value: function compare(oldValue, newValue) {
      return isSame(toJS(oldValue), toJS(newValue));
    }
  }, {
    key: "autoCreate",
    value: function autoCreate() {
      var record = this.record;

      if (record) {
        return record;
      }

      var dataSet = this.dataSet,
          name = this.name,
          dataIndex = this.dataIndex;

      if (dataSet && name) {
        return dataSet.create({}, dataIndex);
      }
    }
  }, {
    key: "setValue",
    value: function setValue(value, noVaidate) {
      var _this5 = this;

      if (!this.readOnly) {
        if (this.multiple || this.range ? isArrayLike(value) && !value.length : isNil(value) || value === '') {
          value = this.emptyValue;
        }

        var name = this.name,
            dataSet = this.dataSet,
            trim = this.trim,
            format = this.format;
        var _this$props4 = this.props,
            _this$props4$onChange = _this$props4.onChange,
            onChange = _this$props4$onChange === void 0 ? noop : _this$props4$onChange,
            _this$props4$onBefore = _this$props4.onBeforeChange,
            onBeforeChange = _this$props4$onBefore === void 0 ? noop : _this$props4$onBefore;
        var old = toJS(this.getOldValue());

        if (!dataSet || !name) {
          value = formatString(value, {
            trim: trim,
            format: format
          });
        }

        var updateAndValidate = function updateAndValidate() {
          if (dataSet && name) {
            var record = _this5.autoCreate();

            if (record) {
              var field = _this5.field;

              if (field && !field.get('defaultValidationMessages', record)) {
                field.set('defaultValidationMessages', _this5.defaultValidationMessages);
              }

              record.set(name, value);
            }
          } else if (!noVaidate) {
            _this5.validate(value, false);
          }
        }; // 转成实际的数据再进行判断


        if (!this.compare(old, toJS(value))) {
          var formNode = this.context.formNode;
          var storedValue = this.value;
          var beforeChange = onBeforeChange(value, old, formNode);
          var resolveCallback = action(function () {
            updateAndValidate();
            onChange(value, old, formNode);

            _this5.afterSetValue();
          });

          if (isPromise(beforeChange)) {
            this.value = value;

            var rejectCallback = function rejectCallback() {
              _this5.value = storedValue;
            };

            beforeChange.then(function (result) {
              return result === false ? rejectCallback() : resolveCallback();
            });
          } else if (beforeChange !== false) {
            resolveCallback();
            this.value = value;
          }
        } else {
          updateAndValidate();
        }
      }
    }
  }, {
    key: "afterSetValue",
    value: function afterSetValue() {// noop
    }
  }, {
    key: "renderRangeValue",
    value: function renderRangeValue(value, repeat) {
      return _renderRangeValue(value, {
        repeat: repeat,
        processRenderer: this.processRenderer
      });
    }
  }, {
    key: "getValueKey",
    value: function getValueKey(v) {
      return _getValueKey(v);
    }
  }, {
    key: "isMultipleBlockDisabled",
    value: function isMultipleBlockDisabled(_v) {
      return this.disabled;
    }
  }, {
    key: "renderMultipleValues",
    value: function renderMultipleValues(readOnly) {
      var prefixCls = this.prefixCls,
          range = this.range,
          disabled = this.disabled,
          _this$props5 = this.props,
          _this$props5$maxTagCo = _this$props5.maxTagCount,
          maxTagCount = _this$props5$maxTagCo === void 0 ? this.getContextConfig('fieldMaxTagCount') : _this$props5$maxTagCo,
          _this$props5$maxTagPl = _this$props5.maxTagPlaceholder,
          maxTagPlaceholder = _this$props5$maxTagPl === void 0 ? this.getContextConfig('fieldMaxTagPlaceholder') : _this$props5$maxTagPl,
          tagRenderer = _this$props5.tagRenderer;

      var values = _renderMultipleValues(this.getValue(), {
        range: range,
        maxTagCount: maxTagCount,
        maxTagPlaceholder: maxTagPlaceholder,
        prefixCls: prefixCls,
        disabled: disabled,
        tagRenderer: tagRenderer,
        readOnly: this.readOnly || readOnly,
        validationResults: this.getValidationResults(),
        isMultipleBlockDisabled: this.isMultipleBlockDisabled,
        processRenderer: this.processRenderer,
        renderValidationResult: this.renderValidationResult,
        handleMultipleValueRemove: this.handleMutipleValueRemove,
        isValidationMessageHidden: this.isValidationMessageHidden,
        showValidationMessage: this.showValidationMessage,
        getKey: this.getValueKey
      });

      this.multipleValidateMessageLength = values.multipleValidateMessageLength;
      return values;
    }
  }, {
    key: "clear",
    value: function clear() {
      var _this$props$onClear = this.props.onClear,
          onClear = _this$props$onClear === void 0 ? noop : _this$props$onClear;
      this.setValue(this.emptyValue);
      this.rangeValue = this.isFocused ? [undefined, undefined] : undefined;
      onClear();
    }
  }, {
    key: "checkValidity",
    value: function () {
      var _checkValidity = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
        var name, valid, _this$props$onInvalid, onInvalid, validationResults, currentValidationResult;

        return _regeneratorRuntime.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                name = this.name;
                _context.next = 3;
                return this.validate();

              case 3:
                valid = _context.sent;
                _this$props$onInvalid = this.props.onInvalid, onInvalid = _this$props$onInvalid === void 0 ? noop : _this$props$onInvalid;

                if (!valid) {
                  validationResults = this.getValidationResults();

                  if (validationResults) {
                    currentValidationResult = validationResults[0];
                    onInvalid(validationResults, new Validity(currentValidationResult ? _defineProperty({}, currentValidationResult.ruleName, true) : undefined), name);
                  }
                }

                return _context.abrupt("return", valid);

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

      function checkValidity() {
        return _checkValidity.apply(this, arguments);
      }

      return checkValidity;
    }()
  }, {
    key: "validate",
    value: function validate(value) {
      var _this6 = this;

      var report = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;

      if (!this.props.noValidate) {
        if (value === undefined) {
          value = this.multiple ? this.getValues() : this.getValue();
        }

        var field = this.field,
            record = this.record,
            name = this.name,
            dataSet = this.dataSet;
        return Validator.checkValidity(value, field && record ? {
          dataSet: dataSet,
          record: record,
          name: name
        } : this.getValidatorProps(), field && record ? field.getValidatorPropGetter(record) : this.getValidatorProp.bind(this)).then(action(function (_ref4) {
          var valid = _ref4.valid,
              validationResults = _ref4.validationResults,
              validatorProps = _ref4.validatorProps;

          if (record && name) {
            record.setValidationError(name, validationResults);
          } else {
            _this6.validationResults = validationResults;
          }

          if (report) {
            Validator.report(validationResults, validatorProps);
            var formNode = _this6.context.formNode;

            if (formNode && !formNode.validating) {
              formNode.reportValidity(valid);
            }
          }

          return valid;
        }));
      }

      return Promise.resolve(true);
    }
  }, {
    key: "isDisabled",
    value: function isDisabled() {
      if (_get(_getPrototypeOf(FormField.prototype), "isDisabled", this).call(this)) {
        return true;
      }

      var field = this.field,
          record = this.record;

      if (field) {
        var disabled = field.get('disabled', record);

        if (disabled) {
          return true;
        }

        var cascadeMap = field.get('cascadeMap', record);

        if (cascadeMap && (!record || Object.keys(cascadeMap).some(function (cascade) {
          if (isObject(record.get(cascadeMap[cascade]))) {
            return isLdEmpty(record.get(cascadeMap[cascade]));
          }

          return isNil(record.get(cascadeMap[cascade]));
        }))) {
          return true;
        }
      }

      return false;
    }
  }, {
    key: "reset",
    value: function reset() {
      if (!this.isControlled && !this.dataSet) {
        this.setValue(this.props.defaultValue, true);
      }

      var record = this.record,
          name = this.name;

      if (record && name) {
        record.clearValidationError(name);
      } else {
        this.validationResults = undefined;
      }
    }
  }, {
    key: "getFieldType",
    value: function getFieldType() {
      var field = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.field;
      return field && field.get('type', this.record) || FieldType.string;
    }
  }, {
    key: "getProp",
    value: function getProp(propName) {
      var fieldPropName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : propName;
      var field = this.field,
          observableProps = this.observableProps,
          record = this.record;
      return defaultTo(field && field.get(fieldPropName, record), propName in observableProps ? observableProps[propName] : this.props[propName]);
    }
    /**
     * 显示类属性值获取（组件属性优先级高于 DataSet Field 属性优先级）
     * @param propName 组件属性名
     * @param fieldPropName Field 字段属性名
     * @returns
     */

  }, {
    key: "getDisplayProp",
    value: function getDisplayProp(propName) {
      var fieldPropName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : propName;
      var field = this.field,
          observableProps = this.observableProps,
          record = this.record;
      return defaultTo(propName in observableProps ? observableProps[propName] : this.props[propName], field && field.get(fieldPropName, record));
    }
  }, {
    key: "getTooltipValidationMessage",
    value: function getTooltipValidationMessage() {
      var _inTable = this.props._inTable;

      if (!_inTable && !(!!(this.multiple && this.getValues().length) && !this.getProp('validator') || this.multipleValidateMessageLength > 0)) {
        var validationMessage = this.renderValidationResult();

        if (!this.isValidationMessageHidden(validationMessage)) {
          return validationMessage;
        }
      }
    }
  }, {
    key: "renderHighLight",
    value: function renderHighLight() {
      var wrapper = this.renderWrapper();
      var highlight = this.highlight,
          dataSet = this.dataSet,
          record = this.record,
          name = this.name;

      if (highlight) {
        var hidden = !(this.hasFloatLabel || this.showValidation === ShowValidation.newLine || this.valid);
        var highlightWrapper = this.highlightRenderer(transformHighlightProps(highlight, {
          dataSet: dataSet,
          record: record,
          name: name,
          hidden: hidden
        }), wrapper);

        if ( /*#__PURE__*/isValidElement(highlightWrapper)) {
          return highlightWrapper;
        }
      }

      return wrapper;
    }
  }, {
    key: "render",
    value: function render() {
      var wrapper = this.renderHighLight();
      var help = this.renderHelpMessage();

      if (this.hasFloatLabel || this.showValidation === ShowValidation.newLine) {
        var message = this.renderValidationResult();
        return [/*#__PURE__*/isValidElement(wrapper) ? /*#__PURE__*/cloneElement(wrapper, {
          key: 'wrapper'
        }) : wrapper, message && /*#__PURE__*/React.createElement(Animate, {
          transitionName: "show-error",
          component: "",
          transitionAppear: true,
          key: "validation-message"
        }, message), help];
      }

      return /*#__PURE__*/React.createElement(React.Fragment, null, wrapper, help);
    }
  }, {
    key: "forcePositionChanged",
    value: function forcePositionChanged() {// noop
    }
  }], [{
    key: "contextType",
    get: function get() {
      return FormContext;
    }
  }]);

  return FormField;
}(DataSetComponent);
FormField.defaultProps = {
  readOnly: false,
  disabled: false,
  noValidate: false,
  trim: FieldTrim.both
};

__decorate([observable], FormField.prototype, "floatLabelOffsetX", void 0);

__decorate([observable], FormField.prototype, "rangeTarget", void 0);

__decorate([observable], FormField.prototype, "rangeValue", void 0);

__decorate([observable], FormField.prototype, "$validator", void 0);

__decorate([observable], FormField.prototype, "validationResults", void 0);

__decorate([computed], FormField.prototype, "editable", null);

__decorate([computed], FormField.prototype, "dataSet", null);

__decorate([computed], FormField.prototype, "record", null);

__decorate([computed], FormField.prototype, "dataIndex", null);

__decorate([computed], FormField.prototype, "field", null);

__decorate([computed], FormField.prototype, "valid", null);

__decorate([computed], FormField.prototype, "readOnly", null);

__decorate([computed], FormField.prototype, "showValidation", null);

__decorate([computed], FormField.prototype, "showHelp", null);

__decorate([computed], FormField.prototype, "highlightRenderer", null);

__decorate([autobind], FormField.prototype, "defaultRenderer", null);

__decorate([autobind], FormField.prototype, "isValidationMessageHidden", null);

__decorate([autobind], FormField.prototype, "showValidationMessage", null);

__decorate([autobind], FormField.prototype, "renderValidationResult", null);

__decorate([autobind], FormField.prototype, "handleMouseEnter", null);

__decorate([autobind], FormField.prototype, "handleMouseLeave", null);

__decorate([autobind], FormField.prototype, "handleFloatLabelMouseEnter", null);

__decorate([autobind], FormField.prototype, "handleFocus", null);

__decorate([autobind], FormField.prototype, "handleBlur", null);

__decorate([autobind], FormField.prototype, "handleCompositionStart", null);

__decorate([autobind], FormField.prototype, "handleChange", null);

__decorate([autobind], FormField.prototype, "handleKeyDown", null);

__decorate([autobind], FormField.prototype, "handleMutipleValueRemove", null);

__decorate([autobind], FormField.prototype, "processRenderer", null);

__decorate([action], FormField.prototype, "prepareSetValue", null);

__decorate([action], FormField.prototype, "removeValues", null);

__decorate([action], FormField.prototype, "removeLastValue", null);

__decorate([action], FormField.prototype, "beginRange", null);

__decorate([action], FormField.prototype, "endRange", null);

__decorate([action], FormField.prototype, "setRangeTarget", null);

__decorate([autobind], FormField.prototype, "compare", null);

__decorate([action], FormField.prototype, "setValue", null);

__decorate([autobind], FormField.prototype, "isMultipleBlockDisabled", null);

__decorate([action], FormField.prototype, "clear", null);

__decorate([action], FormField.prototype, "validate", null);

__decorate([autobind, action], FormField.prototype, "reset", null);

__decorate([autobind], FormField.prototype, "getTooltipValidationMessage", null);

var ObserverFormField = /*#__PURE__*/function (_FormField) {
  _inherits(ObserverFormField, _FormField);

  var _super2 = _createSuper(ObserverFormField);

  function ObserverFormField() {
    _classCallCheck(this, ObserverFormField);

    return _super2.apply(this, arguments);
  }

  return _createClass(ObserverFormField);
}(FormField);

ObserverFormField.defaultProps = FormField.defaultProps;
ObserverFormField = __decorate([observer], ObserverFormField);
export default ObserverFormField;
//# sourceMappingURL=FormField.js.map
