import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _extends from "@babel/runtime/helpers/extends";
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
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 { __decorate } from "tslib";
import React, { isValidElement } from 'react';
import { observer } from 'mobx-react';
import Icon from '../../../es/icon';
import warning from '../../../es/_util/warning';
import { action, computed, isArrayLike, observable, runInAction, toJS } from 'mobx';
import isNumber from 'lodash/isNumber';
import isNil from 'lodash/isNil';
import noop from 'lodash/noop';
import isPlainObject from 'lodash/isPlainObject';
import { isMoment } from 'moment';
import defaultTo from 'lodash/defaultTo';
import Row from '../../../es/row';
import classNames from 'classnames';
import ObjectChainValue from '../_util/ObjectChainValue';
import DataSetComponent from '../data-set/DataSetComponent';
import ScreeningOption from './ScreeningOption';
import normalizeOptions from '../option/normalizeOptions';
import autobind from '../_util/autobind';
import isEmpty from '../_util/isEmpty';
import { getDateFormatByField, toMultipleValue } from '../field/utils';
import { FieldType } from '../data-set/enum';
import { formatString } from '../formatter';
import isSame from '../_util/isSame';
import isSameLike from '../_util/isSameLike';
import ObserverButton from '../button/Button';
import { $l } from '../locale-context';
var disabledField = '__disabled';

var expandedButton = function expandedButton(iconExpanded) {
  if (iconExpanded === true) {
    return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", null, "".concat($l('Screening', 'pack_up'))), /*#__PURE__*/React.createElement(Icon, {
      type: "expand_less"
    }));
  }

  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", null, "".concat($l('Screening', 'more'))), /*#__PURE__*/React.createElement(Icon, {
    type: "expand_more"
  }));
};

export function getItemKey(record, text, value) {
  return "item-".concat(value || record.id, "-").concat(( /*#__PURE__*/isValidElement(text) ? text.key : text) || record.id);
}

function getSimpleValue(value, valueField) {
  if (isPlainObject(value)) {
    return ObjectChainValue.get(value, valueField);
  }

  return value;
}

var Screening = /*#__PURE__*/function (_DataSetComponent) {
  _inherits(Screening, _DataSetComponent);

  var _super = _createSuper(Screening);

  function Screening(props, context) {
    var _this;

    _classCallCheck(this, Screening);

    _this = _super.call(this, props, context);
    _this.emptyValue = null;
    _this.text = null;

    _this.handleExpanedClick = function () {
      _this.iconExpanded = !_this.iconExpanded;
    };
    /**
     * 提交值，触发dataSet修改和提交方法。
     */


    _this.handleConfirm = function () {
      var onConfirm = _this.props.onConfirm;

      var _assertThisInitialize = _assertThisInitialized(_this),
          value = _assertThisInitialize.value,
          dataSet = _assertThisInitialize.dataSet,
          name = _assertThisInitialize.name,
          dataIndex = _assertThisInitialize.observableProps.dataIndex;

      if (value && name && dataSet) {
        (_this.record || dataSet.create({}, dataIndex)).set(name, value);

        if (onConfirm) {
          onConfirm({
            value: _this.value,
            fieldName: _this.name
          });
        }
      }
    };

    _this.handleSelect = function (info) {
      var record = info.value;

      _this.choose(record);
    };

    _this.handleDeselect = function (info) {
      var record = info.value;

      _this.unChoose(record);
    };

    _this.handleClick = function (_info) {// noop
    };

    _this.getScreeningOption = function () {
      var _this$props = _this.props,
          colProps = _this$props.colProps,
          optionRenderer = _this$props.optionRenderer;

      var _assertThisInitialize2 = _assertThisInitialized(_this),
          options = _assertThisInitialize2.options,
          textField = _assertThisInitialize2.textField,
          valueField = _assertThisInitialize2.valueField,
          multiple = _assertThisInitialize2.multiple;

      if (!options) {
        return null;
      }

      var data = options.data;

      if (!isEmpty(data)) {
        return data.map(function (record) {
          var value = record.get(valueField);
          var text = record.get(textField);
          var key = getItemKey(record, text, value);
          var isSelected = false;

          var valueRecord = _this.processRecordToObject(record);

          var selectedValue = toJS(_this.value);

          if (multiple) {
            if (selectedValue && selectedValue.length > 0) {
              isSelected = selectedValue.some(function (itemValue) {
                return isSame(itemValue, valueRecord);
              });
            }
          } else if (isSame(valueRecord, selectedValue)) {
            isSelected = true;
          }

          var textNode = /*#__PURE__*/React.createElement("span", {
            className: "".concat(_this.prefixCls, "-option-text")
          }, text);

          var screeningOptionProps = _objectSpread(_objectSpread({}, colProps), {}, {
            onSelect: _this.handleSelect,
            onDeselect: _this.handleDeselect,
            onClick: _this.handleClick,
            value: record,
            optionkey: key,
            multiple: multiple,
            isSelected: isSelected,
            prefixCls: _this.prefixCls,
            children: textNode
          });

          if (optionRenderer) {
            screeningOptionProps.optionRender = optionRenderer({
              record: record,
              text: text,
              value: value
            });
          }

          return /*#__PURE__*/React.createElement(ScreeningOption, _extends({
            key: key
          }, screeningOptionProps));
        });
      }

      return null;
    };

    _this.handleMultiple = function () {
      _this.screeningMultiple = !_this.screeningMultiple;
    };

    _this.handleClear = function () {
      _this.setValue(_this.emptyValue);

      _this.value = _this.emptyValue;
      _this.text = _this.emptyValue;
    };

    _this.handleCancel = function () {
      _this.handleClear();

      _this.handleMultiple();
    };

    runInAction(function () {
      _this.iconExpanded = false;
      _this.screeningMultiple = false;

      if (_this.name && _this.dataSet && _this.record) {
        var value = _this.record.get(_this.name);

        if (!isNil(value)) {
          _this.value = value;
        }
      }
    });
    return _this;
  }

  _createClass(Screening, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      _get(_getPrototypeOf(Screening.prototype), "componentDidMount", this).call(this);

      var onRef = this.props.onRef;

      if (onRef) {
        onRef(this);
      }
    }
    /**
     * return the record: dataIndex record, current, undefined
     */

  }, {
    key: "record",
    get: function get() {
      var _this$observableProps = this.observableProps,
          record = _this$observableProps.record,
          dataSet = _this$observableProps.dataSet,
          dataIndex = _this$observableProps.dataIndex;

      if (record) {
        return record;
      }

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

        return dataSet.current;
      }

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

      runInAction(function () {
        _this2.observableProps.value = value;
      });
    } // @computed

  }, {
    key: "editable",
    get: function get() {
      return !this.disabled && !this.isReadOnly();
    }
    /**
     * 判断是否展示更多按钮
     */

  }, {
    key: "needExpandButton",
    get: function get() {
      var colProps = this.props.colProps;

      if (colProps) {
        var span = colProps.span;

        if (isNumber(span) && span >= 1) {
          var colNumber = 24 / span;

          if (this.options && this.options.length < colNumber) {
            return false;
          }
        }
      }

      return true;
    }
  }, {
    key: "name",
    get: function get() {
      return this.observableProps.name;
    }
  }, {
    key: "primitive",
    get: function get() {
      var type = this.getProp('type');
      return this.observableProps.primitiveValue !== false && type !== FieldType.object;
    }
    /**
     * get field message: recordField,dsField,undefined
     */

  }, {
    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 && dataSet) {
        return dataSet.getField(name);
      }

      return undefined;
    }
  }, {
    key: "getProp",
    value: function getProp(propName) {
      var field = this.field;
      return defaultTo(field && field.get(propName, this.record), this.props[propName]);
    }
  }, {
    key: "handleChange",
    value: function handleChange(e) {
      e.preventDefault();
      e.stopPropagation();
    }
  }, {
    key: "options",
    get: function get() {
      var field = this.field,
          record = this.record,
          textField = this.textField,
          valueField = this.valueField,
          multiple = this.multiple,
          _this$observableProps2 = this.observableProps,
          children = _this$observableProps2.children,
          options = _this$observableProps2.options;
      return options || field && field.getOptions(record) || normalizeOptions({
        textField: textField,
        valueField: valueField,
        disabledField: disabledField,
        multiple: multiple,
        children: children,
        getConfig: this.getContextConfig
      });
    }
  }, {
    key: "multiple",
    get: function get() {
      return toJS(this.screeningMultiple) || !!this.getProp('multiple');
    }
  }, {
    key: "textField",
    get: function get() {
      return this.getProp('textField') || 'meaning';
    }
  }, {
    key: "valueField",
    get: function get() {
      return this.getProp('valueField') || 'value';
    }
  }, {
    key: "getFieldType",
    value: function getFieldType() {
      var field = this.field;
      return field && field.get('type', this.record) || FieldType.string;
    }
  }, {
    key: "getDateFormat",
    value: function getDateFormat() {
      return getDateFormatByField(this.field, this.getFieldType(), this.record);
    }
  }, {
    key: "choose",
    value: function choose(record) {
      if (record) {
        this.handleOptionSelect(record);
      }
    }
  }, {
    key: "unChoose",
    value: function unChoose(record) {
      if (record) {
        this.handleOptionUnSelect(record);
      }
    }
  }, {
    key: "handleOptionSelect",
    value: function handleOptionSelect(record) {
      this.prepareSetValue(this.processRecordToObject(record));
    }
  }, {
    key: "handleOptionUnSelect",
    value: function handleOptionUnSelect(record) {
      var valueField = this.valueField;
      var newValue = record.get(valueField);
      this.removeValue(newValue, -1);
    }
  }, {
    key: "getDataSetValue",
    value: function getDataSetValue() {
      var record = this.record,
          name = this.name;

      if (record) {
        return record.get(name);
      }
    }
  }, {
    key: "getValue",
    value: function getValue() {
      var name = this.name,
          multiple = this.multiple;

      if (multiple) {
        return this.value;
      }

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

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

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

        if (values.length) {
          this.setValue([].concat(_toConsumableArray(oldValues), values));
        } else if (!oldValues.length) {
          this.setValue(this.emptyValue);
        }
      } else {
        this.setValue(values.pop());
      }
    }
  }, {
    key: "getValueKey",
    value: function getValueKey(v) {
      if (isArrayLike(v)) {
        return v.join(',');
      }

      return v;
    }
  }, {
    key: "removeValues",
    value: function removeValues(values) {
      var _this3 = this;

      var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
      var repeat;
      this.setValue(values.reduce(function (oldValues, value) {
        repeat = 0;
        return oldValues.filter(function (v) {
          if (_this3.getValueKey(v) === _this3.getValueKey(value)) {
            if (index === -1 || repeat === index) {
              _this3.afterRemoveValue(value, repeat++);

              return false;
            }

            repeat++;
          }

          return true;
        });
      }, this.getValues()));
    }
  }, {
    key: "afterRemoveValue",
    value: function afterRemoveValue(_value, _repeat) {// noop
    }
  }, {
    key: "removeValue",
    value: function removeValue(value) {
      var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
      this.removeValues([value], index);
    }
  }, {
    key: "isReadOnly",
    value: function isReadOnly() {
      return this.getProp('readOnly') || !this.props.onChange;
    }
  }, {
    key: "setValue",
    value: function setValue(value) {
      var _this4 = this;

      var onConfirm = this.props.onConfirm;

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

        var name = this.name,
            dataSet = this.dataSet,
            dataIndex = this.observableProps.dataIndex;
        var _this$props$onChange = this.props.onChange,
            onChange = _this$props$onChange === void 0 ? noop : _this$props$onChange;
        var formNode = this.context.formNode;
        var old = this.getOldValue();

        if (dataSet && name && !this.multiple) {
          (this.record || dataSet.create({}, dataIndex)).set(name, value);
        } else {
          value = formatString(value, {});
        } // 转成实际的数据再进行判断


        if (!isSame(toJS(old), toJS(value))) {
          onChange(value, toJS(old), formNode);

          if (this.multiple && value) {
            this.text = value.map(function (item) {
              return _this4.processValue(item);
            });
          } else if (value) {
            this.text = this.processValue(value);

            if (onConfirm) {
              onConfirm({
                value: value,
                fieldName: this.name
              });
            }
          }
        }

        this.value = value;
      }
    }
  }, {
    key: "prepareSetValue",
    value: function prepareSetValue() {
      for (var _len2 = arguments.length, value = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
        value[_key2] = arguments[_key2];
      }

      var values = value.filter(function (item) {
        return !isEmpty(item);
      });
      this.addValue.apply(this, _toConsumableArray(values));
    }
  }, {
    key: "findByValue",
    value: function findByValue(value) {
      var valueField = this.valueField;
      var autoType = this.getProp('type') === FieldType.auto;
      value = getSimpleValue(value, valueField);
      return this.options.find(function (record) {
        return autoType ? isSameLike(record.get(valueField), value) : isSame(record.get(valueField), value);
      });
    }
  }, {
    key: "processObjectValue",
    value: function processObjectValue(value, textField) {
      if (!isNil(value)) {
        if (isPlainObject(value)) {
          return ObjectChainValue.get(value, textField);
        }

        var found = this.findByValue(value);

        if (found) {
          return found.get(textField);
        }
      }
    }
  }, {
    key: "processValueNormal",
    value: function processValueNormal(value) {
      if (!isNil(value)) {
        if (isMoment(value)) {
          return value.format(this.getDateFormat());
        }

        return value.toString();
      }

      return '';
    }
  }, {
    key: "processLookupValue",
    value: function processLookupValue(value) {
      var field = this.field,
          textField = this.textField,
          primitive = this.primitive,
          record = this.record;

      if (primitive && field && field.getLookup(record)) {
        return this.processValueNormal(field.getText(value, undefined, record));
      }

      return this.processValueNormal(this.processObjectValue(value, textField));
    }
  }, {
    key: "processValue",
    value: function processValue(value) {
      var text = this.processLookupValue(value);

      if (isEmpty(text)) {
        if (isPlainObject(value)) {
          return ObjectChainValue.get(value, this.valueField) || '';
        }

        return this.processValueNormal(value);
      }

      return text;
    }
  }, {
    key: "processRecordToObject",
    value: function processRecordToObject(record) {
      var primitive = this.primitive,
          valueField = this.valueField;
      return primitive ? record.get(valueField) : record.toData();
    }
  }, {
    key: "getTextNode",
    value: function getTextNode() {
      var text = this.isFocused && this.editable ? this.processValue(this.getValue()) : this.processRenderer(this.getValue());
      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) {
      var record = this.record,
          dataSet = this.dataSet,
          _this$props2 = this.props,
          renderer = _this$props2.renderer,
          onConfirm = _this$props2.onConfirm;
      var text = this.processText(this.getText(value));
      return renderer ? renderer({
        options: this.options,
        name: this.name,
        dataSet: dataSet,
        onConfirm: onConfirm,
        record: record
      }) : text;
    }
  }, {
    key: "getObservableProps",
    value: function getObservableProps(props, context) {
      return _objectSpread(_objectSpread({}, _get(_getPrototypeOf(Screening.prototype), "getObservableProps", this).call(this, props, context)), {}, {
        name: props.name,
        record: 'record' in props ? props.record : context.record,
        dataSet: 'dataSet' in props ? props.dataSet : context.dataSet,
        dataIndex: defaultTo(props.dataIndex, context.dataIndex),
        value: this.observableProps || 'value' in props ? props.value : props.defaultValue,
        primitiveValue: props.primitiveValue
      });
    }
  }, {
    key: "getOmitPropsKeys",
    value: function getOmitPropsKeys() {
      return _get(_getPrototypeOf(Screening.prototype), "getOmitPropsKeys", this).call(this).concat(['record', 'defaultValue', 'dataIndex', 'onEnterDown', 'onClear', 'readOnly', 'renderer', 'pristine', 'primitiveValue', 'trim', 'onRef', 'onConfirm', 'colProps']);
    }
  }, {
    key: "getOtherProps",
    value: function getOtherProps() {
      var otherProps = _get(_getPrototypeOf(Screening.prototype), "getOtherProps", this).call(this);

      otherProps.onChange = this.disabled ? noop : this.handleChange;
      return otherProps;
    }
  }, {
    key: "getLabel",
    value: function getLabel() {
      return this.getProp('label');
    }
  }, {
    key: "render",
    value: function render() {
      var _classNames;

      var iconExpanded = this.iconExpanded,
          prefixCls = this.prefixCls,
          multiple = this.multiple;
      var _this$props3 = this.props,
          renderer = _this$props3.renderer,
          onConfirm = _this$props3.onConfirm;
      var label = this.getLabel();
      var multipleButton = /*#__PURE__*/React.createElement("div", {
        className: "".concat(prefixCls, "-multiple"),
        onClick: this.handleMultiple
      }, /*#__PURE__*/React.createElement(Icon, {
        type: "add"
      }), /*#__PURE__*/React.createElement("span", null, "".concat($l('Screening', 'multi_select'))));
      var expandButtonContainer = this.needExpandButton && /*#__PURE__*/React.createElement("div", {
        className: "".concat(prefixCls, "-expanded"),
        onClick: this.handleExpanedClick
      }, expandedButton(iconExpanded));
      var labelNode = /*#__PURE__*/React.createElement("span", {
        className: "".concat(prefixCls, "-label")
      }, "".concat(label, ":"));
      var allClassName = classNames((_classNames = {}, _defineProperty(_classNames, "".concat(prefixCls, "-multiple"), multiple), _defineProperty(_classNames, "".concat(prefixCls, "-more"), iconExpanded), _classNames), this.getMergedClassNames());
      return /*#__PURE__*/React.createElement("div", _extends({}, this.getMergedProps(), {
        className: allClassName
      }), renderer ? renderer({
        options: this.options,
        name: this.name,
        dataSet: this.dataSet,
        onConfirm: onConfirm,
        record: this.record
      }) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
        className: "".concat(prefixCls, "-title")
      }, labelNode), /*#__PURE__*/React.createElement("div", {
        className: "".concat(prefixCls, "-content")
      }, /*#__PURE__*/React.createElement("div", {
        className: "".concat(prefixCls, "-scroll")
      }, /*#__PURE__*/React.createElement(Row, null, this.getScreeningOption()))), !this.multiple && /*#__PURE__*/React.createElement("div", {
        className: "".concat(prefixCls, "-operation")
      }, expandButtonContainer, multipleButton), this.multiple && /*#__PURE__*/React.createElement("div", {
        className: "".concat(prefixCls, "-footer")
      }, /*#__PURE__*/React.createElement(ObserverButton, {
        onClick: this.handleConfirm
      }, "".concat($l('Screening', 'confirm'))), /*#__PURE__*/React.createElement(ObserverButton, {
        onClick: this.handleCancel
      }, "".concat($l('Screening', 'cancel'))))));
    }
  }]);

  return Screening;
}(DataSetComponent);

Screening.displayName = 'ScreeningItem';
Screening.defaultProps = {
  suffixCls: 'screening-item',
  multiple: false,
  colProps: {
    span: 4
  }
};

__decorate([observable], Screening.prototype, "iconExpanded", void 0);

__decorate([observable], Screening.prototype, "screeningMultiple", void 0);

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

__decorate([computed], Screening.prototype, "value", null);

__decorate([computed], Screening.prototype, "needExpandButton", null);

__decorate([computed], Screening.prototype, "name", null);

__decorate([computed], Screening.prototype, "primitive", null);

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

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

__decorate([computed], Screening.prototype, "options", null);

__decorate([computed], Screening.prototype, "multiple", null);

__decorate([computed], Screening.prototype, "textField", null);

__decorate([computed], Screening.prototype, "valueField", null);

__decorate([action], Screening.prototype, "handleExpanedClick", void 0);

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

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

__decorate([action], Screening.prototype, "handleMultiple", void 0);

__decorate([action], Screening.prototype, "handleClear", void 0);

Screening = __decorate([observer], Screening);
export default Screening;
//# sourceMappingURL=ScreeningItem.js.map
