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

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

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

function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }

function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }

function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import Button from '../../button';
import Icon from '../../icon';
import ConfigProvider from '../../config-provider';
import zhCN from '../../locale/zh-cn';
import { func, obj } from '../../util';
import TransferPanel from '../view/transfer-panel';
var config = ConfigProvider.config;
var bindCtx = func.bindCtx;
var pickOthers = obj.pickOthers;
/**
 * Transfer
 */

var Transfer =
/*#__PURE__*/
function (_Component) {
  _inherits(Transfer, _Component);

  _createClass(Transfer, null, [{
    key: "normalizeValue",
    value: function normalizeValue(value) {
      if (value) {
        if (Array.isArray(value)) {
          return value;
        }
        /* istanbul ignore next */


        return [value];
      }

      return [];
    }
  }]);

  function Transfer(props, context) {
    var _this;

    _classCallCheck(this, Transfer);

    _this = _possibleConstructorReturn(this, _getPrototypeOf(Transfer).call(this, props, context));
    var value = props.value,
        defaultValue = props.defaultValue,
        defaultLeftChecked = props.defaultLeftChecked,
        defaultRightChecked = props.defaultRightChecked,
        dataSource = props.dataSource,
        rtl = props.rtl,
        operations = props.operations;

    if (operations.length === 0) {
      operations.push(React.createElement(Icon, {
        rtl: rtl,
        type: "chevron-right"
      }));
      operations.push(React.createElement(Icon, {
        rtl: rtl,
        type: "chevron-left"
      }));
    }

    var _this$filterCheckedVa = _this.filterCheckedValue(Transfer.normalizeValue(defaultLeftChecked), Transfer.normalizeValue(defaultRightChecked), dataSource),
        left = _this$filterCheckedVa.left,
        right = _this$filterCheckedVa.right;

    _this.state = {
      value: Transfer.normalizeValue('value' in props ? value : defaultValue),
      leftCheckedValue: left,
      rightCheckedValue: right
    };
    _this.leftValue = _this.getLeftValue(dataSource, _this.state.value);
    bindCtx(_assertThisInitialized(_this), ['handlePanelChange', 'handlePanelSort', 'handleMoveItem', 'handleSimpleMove', 'handleSimpleMoveAll']);
    return _this;
  }

  _createClass(Transfer, [{
    key: "UNSAFE_componentWillReceiveProps",
    value: function UNSAFE_componentWillReceiveProps(nextProps) {
      var st = {};
      var newValue;

      if ('value' in nextProps) {
        var value = Transfer.normalizeValue(nextProps.value);
        st.value = value;
        newValue = value;
      } else {
        /* istanbul ignore next */
        newValue = this.state.value;
      }

      this.leftValue = this.getLeftValue(nextProps.dataSource, newValue);

      var _this$filterCheckedVa2 = this.filterCheckedValue(this.state.leftCheckedValue, this.state.rightCheckedValue, nextProps.dataSource),
          left = _this$filterCheckedVa2.left,
          right = _this$filterCheckedVa2.right;

      st.leftCheckedValue = left;
      st.rightCheckedValue = right;
      this.setState(st);
    }
  }, {
    key: "filterCheckedValue",
    value: function filterCheckedValue(left, right, dataSource) {
      var result = {
        left: [],
        right: []
      };

      if (left.length || right.length) {
        var value = dataSource.map(function (item) {
          return item.value;
        });
        value.forEach(function (itemValue) {
          if (left.indexOf(itemValue) > -1) {
            result.left.push(itemValue);
          } else if (right.indexOf(itemValue) > -1) {
            result.right.push(itemValue);
          }
        });
      }

      return result;
    }
  }, {
    key: "getLeftValue",
    value: function getLeftValue(dataSource, rightValue) {
      return dataSource.map(function (item) {
        return item.value;
      }).filter(function (itemValue) {
        return rightValue.indexOf(itemValue) === -1;
      });
    }
  }, {
    key: "groupDatasource",
    value: function groupDatasource(value, itemValues, dataSource) {
      return value.reduce(function (ret, itemValue) {
        var index = itemValues.indexOf(itemValue);

        if (index > -1) {
          ret.push(dataSource[index]);
        }

        return ret;
      }, []);
    }
  }, {
    key: "handlePanelChange",
    value: function handlePanelChange(position, value) {
      var valuePropName = position === 'left' ? 'leftCheckedValue' : 'rightCheckedValue';
      this.setState(_defineProperty({}, valuePropName, value));
    }
  }, {
    key: "handlePanelSort",
    value: function handlePanelSort(position, dragValue, referenceValue, dragGap) {
      var _this2 = this;

      var value = position === 'right' ? this.state.value : this.leftValue;
      var currentIndex = value.indexOf(dragValue);
      var referenceIndex = value.indexOf(referenceValue);
      var expectIndex = dragGap === 'before' ? referenceIndex : referenceIndex + 1;

      if (currentIndex === expectIndex) {
        return;
      }

      value.splice(currentIndex, 1);

      if (currentIndex < expectIndex) {
        expectIndex -= 1;
      }

      value.splice(expectIndex, 0, dragValue);
      this.setState({
        value: this.state.value
      }, function () {
        _this2.props.onSort(value, position);
      });
    }
  }, {
    key: "handleMoveItem",
    value: function handleMoveItem(direction) {
      var rightValue;
      var leftValue;
      var movedValue;
      var valuePropName;
      var _this$state = this.state,
          value = _this$state.value,
          leftCheckedValue = _this$state.leftCheckedValue,
          rightCheckedValue = _this$state.rightCheckedValue;

      if (direction === 'right') {
        rightValue = leftCheckedValue.concat(value);
        leftValue = this.leftValue.filter(function (itemValue) {
          return leftCheckedValue.indexOf(itemValue) === -1;
        });
        movedValue = leftCheckedValue;
        valuePropName = 'leftCheckedValue';
      } else {
        rightValue = value.filter(function (itemValue) {
          return rightCheckedValue.indexOf(itemValue) === -1;
        });
        leftValue = rightCheckedValue.concat(this.leftValue);
        movedValue = rightCheckedValue;
        valuePropName = 'rightCheckedValue';
      }

      var st = _defineProperty({}, valuePropName, []);

      this.setValueState(st, rightValue, leftValue, movedValue, direction);
    }
  }, {
    key: "handleSimpleMove",
    value: function handleSimpleMove(direction, v) {
      var rightValue;
      var leftValue;
      var value = this.state.value;

      if (direction === 'right') {
        rightValue = [v].concat(value);
        leftValue = this.leftValue.filter(function (itemValue) {
          return itemValue !== v;
        });
      } else {
        rightValue = value.filter(function (itemValue) {
          return itemValue !== v;
        });
        leftValue = [v].concat(this.leftValue);
      }

      this.setValueState({}, rightValue, leftValue, [v], direction);
    }
  }, {
    key: "handleSimpleMoveAll",
    value: function handleSimpleMoveAll(direction) {
      var rightValue;
      var leftValue;
      var movedValue;
      var dataSource = this.props.dataSource;
      var value = this.state.value;
      var disabledValue = dataSource.reduce(function (ret, item) {
        if (item.disabled) {
          ret.push(item.value);
        }

        return ret;
      }, []);

      if (direction === 'right') {
        movedValue = this.leftValue.filter(function (itemValue) {
          return disabledValue.indexOf(itemValue) === -1;
        });
        rightValue = movedValue.concat(value);
        leftValue = this.leftValue.filter(function (itemValue) {
          return disabledValue.indexOf(itemValue) > -1;
        });
      } else {
        movedValue = value.filter(function (itemValue) {
          return disabledValue.indexOf(itemValue) === -1;
        });
        rightValue = value.filter(function (itemValue) {
          return disabledValue.indexOf(itemValue) > -1;
        });
        leftValue = movedValue.concat(this.leftValue);
      }

      this.setValueState({}, rightValue, leftValue, movedValue, direction);
    } // eslint-disable-next-line max-params

  }, {
    key: "setValueState",
    value: function setValueState(st, rightValue, leftValue, movedValue, direction) {
      var _this3 = this;

      var dataSource = this.props.dataSource;

      var callback = function callback() {
        if ('onChange' in _this3.props) {
          var itemValues = dataSource.map(function (item) {
            return item.value;
          });

          var rightData = _this3.groupDatasource(rightValue, itemValues, dataSource);

          var leftData = _this3.groupDatasource(leftValue, itemValues, dataSource);

          var movedData = _this3.groupDatasource(movedValue, itemValues, dataSource);

          _this3.props.onChange(rightValue, rightData, {
            leftValue: leftValue,
            leftData: leftData,
            movedValue: movedValue,
            movedData: movedData,
            direction: direction
          });
        }
      };

      if (!('value' in this.props)) {
        st.value = rightValue;
        this.leftValue = leftValue;
      }

      if (Object.keys(st).length) {
        this.setState(st, callback);
      } else {
        // eslint-disable-next-line callback-return
        callback();
      }
    }
  }, {
    key: "renderCenter",
    value: function renderCenter() {
      var _this$props = this.props,
          prefix = _this$props.prefix,
          mode = _this$props.mode,
          operations = _this$props.operations,
          disabled = _this$props.disabled,
          leftDisabled = _this$props.leftDisabled,
          rightDisabled = _this$props.rightDisabled,
          locale = _this$props.locale;
      var _this$state2 = this.state,
          leftCheckedValue = _this$state2.leftCheckedValue,
          rightCheckedValue = _this$state2.rightCheckedValue;
      return React.createElement("div", {
        className: "".concat(prefix, "transfer-operations")
      }, mode === 'simple' ? React.createElement(Icon, {
        className: "".concat(prefix, "transfer-move"),
        size: "large",
        type: "arrows-swtich-horizontal"
      }) : [React.createElement(Button, {
        "aria-label": locale.moveToRight,
        size: "xs",
        key: "l2r",
        className: "".concat(prefix, "transfer-operation"),
        type: leftCheckedValue.length ? 'primary' : 'normal',
        disabled: leftDisabled || disabled || !leftCheckedValue.length,
        onClick: this.handleMoveItem.bind(this, 'right')
      }, operations[0]), React.createElement(Button, {
        size: "xs",
        "aria-label": locale.moveToLeft,
        key: "r2l",
        className: "".concat(prefix, "transfer-operation"),
        type: rightCheckedValue.length ? 'primary' : 'normal',
        disabled: rightDisabled || disabled || !rightCheckedValue.length,
        onClick: this.handleMoveItem.bind(this, 'left')
      }, operations[1])]);
    }
  }, {
    key: "render",
    value: function render() {
      var _this$props2 = this.props,
          prefix = _this$props2.prefix,
          mode = _this$props2.mode,
          disabled = _this$props2.disabled,
          className = _this$props2.className,
          dataSource = _this$props2.dataSource,
          locale = _this$props2.locale,
          showSearch = _this$props2.showSearch,
          filter = _this$props2.filter,
          onSearch = _this$props2.onSearch,
          leftDisabled = _this$props2.leftDisabled,
          rightDisabled = _this$props2.rightDisabled,
          searchPlaceholder = _this$props2.searchPlaceholder,
          notFoundContent = _this$props2.notFoundContent,
          titles = _this$props2.titles,
          listClassName = _this$props2.listClassName,
          listStyle = _this$props2.listStyle,
          itemRender = _this$props2.itemRender,
          sortable = _this$props2.sortable,
          rtl = _this$props2.rtl,
          id = _this$props2.id,
          children = _this$props2.children,
          showCheckAll = _this$props2.showCheckAll;
      var _this$state3 = this.state,
          value = _this$state3.value,
          leftCheckedValue = _this$state3.leftCheckedValue,
          rightCheckedValue = _this$state3.rightCheckedValue;
      var itemValues = dataSource.map(function (item) {
        return item.value;
      });
      var leftDatasource = this.groupDatasource(this.leftValue, itemValues, dataSource);
      var rightDatasource = this.groupDatasource(value, itemValues, dataSource);
      var panelProps = {
        prefix: prefix,
        mode: mode,
        locale: locale,
        showSearch: showSearch,
        filter: filter,
        onSearch: onSearch,
        searchPlaceholder: searchPlaceholder,
        notFoundContent: notFoundContent,
        listClassName: listClassName,
        listStyle: listStyle,
        itemRender: itemRender,
        onMove: this.handleSimpleMove,
        onMoveAll: this.handleSimpleMoveAll,
        onChange: this.handlePanelChange,
        sortable: sortable,
        onSort: this.handlePanelSort,
        baseId: id,
        customerList: children,
        showCheckAll: showCheckAll
      };
      var others = pickOthers(Object.keys(Transfer.propTypes), this.props);

      if (rtl) {
        others.dir = 'rtl';
      }

      return React.createElement("div", _extends({
        className: cx("".concat(prefix, "transfer"), className),
        id: id
      }, others), React.createElement(TransferPanel, _extends({}, panelProps, {
        position: "left",
        dataSource: leftDatasource,
        disabled: leftDisabled || disabled,
        value: leftCheckedValue,
        title: titles[0]
      })), this.renderCenter(), React.createElement(TransferPanel, _extends({}, panelProps, {
        position: "right",
        dataSource: rightDatasource,
        disabled: rightDisabled || disabled,
        value: rightCheckedValue,
        title: titles[1]
      })));
    }
  }]);

  return Transfer;
}(Component);

_defineProperty(Transfer, "displayName", 'Transfer');

_defineProperty(Transfer, "contextTypes", {
  prefix: PropTypes.string
});

_defineProperty(Transfer, "propTypes", {
  prefix: PropTypes.string,
  pure: PropTypes.bool,
  rtl: PropTypes.bool,
  className: PropTypes.string,

  /**
   * 移动选项模式
   */
  mode: PropTypes.oneOf(['normal', 'simple']),

  /**
   * 数据源
   */
  dataSource: PropTypes.arrayOf(PropTypes.object),

  /**
   * （用于受控）当前值
   */
  value: PropTypes.arrayOf(PropTypes.string),

  /**
   * （用于非受控）初始值
   */
  defaultValue: PropTypes.arrayOf(PropTypes.string),

  /**
   * 值发生改变的时候触发的回调函数
   * @param {Array} value 右面板值
   * @param {Array} data 右面板数据
   * @param {Object} extra 额外参数
   * @param {Array} extra.leftValue 左面板值
   * @param {Array} extra.leftData 左面板数据
   * @param {Array} extra.movedValue 发生移动的值
   * @param {Object} extra.movedData 发生移动的数据
   * @param {String} extra.direction 移动的方向，值为'left'或'right'
   */
  onChange: PropTypes.func,

  /**
   * 是否禁用
   */
  disabled: PropTypes.bool,

  /**
   * 是否禁用左侧面板
   */
  leftDisabled: PropTypes.bool,

  /**
   * 是否禁用右侧面板
   */
  rightDisabled: PropTypes.bool,

  /**
   * 列表项渲染函数
   * @param {Object} data 数据
   * @return {ReactNode} 列表项内容
   */
  itemRender: PropTypes.func,

  /**
   * 是否显示搜索框
   */
  showSearch: PropTypes.bool,

  /**
   * 自定义搜索函数
   * @param {String} searchedValue 搜索的内容
   * @param {Object} data 数据
   * @return {Boolean} 是否匹配到
   * @default 根据 label 属性匹配
   */
  filter: PropTypes.func,

  /**
   * 搜索框输入时触发的回调函数
   * @param {String} searchedValue 搜索的内容
   * @param {String} position 搜索面板的位置
   */
  onSearch: PropTypes.func,

  /**
   * 搜索框占位符
   */
  searchPlaceholder: PropTypes.string,

  /**
   * 列表为空显示内容
   */
  notFoundContent: PropTypes.node,

  /**
   * 左右面板标题
   */
  titles: PropTypes.arrayOf(PropTypes.node),

  /**
   * 向右向左移动按钮显示内容
   * @default [<Icon type="chevron-right" />, <Icon type="chevron-left" />]
   */
  operations: PropTypes.arrayOf(PropTypes.node),

  /**
   * 左面板默认选中值
   */
  defaultLeftChecked: PropTypes.arrayOf(PropTypes.string),

  /**
   * 右面板默认选中值
   */
  defaultRightChecked: PropTypes.arrayOf(PropTypes.string),

  /**
   * 左右面板列表自定义样式类名
   */
  listClassName: PropTypes.string,

  /**
   * 左右面板列表自定义样式对象
   */
  listStyle: PropTypes.object,

  /**
   * 是否允许拖拽排序
   */
  sortable: PropTypes.bool,

  /**
   * 拖拽排序时触发的回调函数
   * @param {Array} value 排序后的值
   * @param {String} position 拖拽的面板位置，值为：left 或 right
   */
  onSort: PropTypes.func,

  /**
   * 自定义国际化文案对象
   */
  locale: PropTypes.object,

  /**
   * 请设置 id 以保证transfer的可访问性
   */
  id: PropTypes.string,

  /**
   * 接收 children 自定义渲染列表
   */
  children: PropTypes.func,

  /**
   * 是否显示底部全选 checkbox
   */
  showCheckAll: PropTypes.bool
});

_defineProperty(Transfer, "defaultProps", {
  prefix: 'next-',
  pure: false,
  mode: 'normal',
  dataSource: [],
  defaultValue: [],
  disabled: false,
  leftDisabled: false,
  rightDisabled: false,
  showCheckAll: true,
  itemRender: function itemRender(data) {
    return data.label;
  },
  showSearch: false,
  filter: function filter(searchedValue, data) {
    var labelString = '';

    var loop = function loop(arg) {
      if (React.isValidElement(arg) && arg.props.children) {
        React.Children.forEach(arg.props.children, loop);
      } else if (typeof arg === 'string') {
        labelString += arg;
      }
    };

    loop(data.label);
    return labelString.length >= searchedValue.length && labelString.indexOf(searchedValue) > -1;
  },
  onSearch: function onSearch() {},
  notFoundContent: 'Not Found',
  titles: [],
  operations: [],
  defaultLeftChecked: [],
  defaultRightChecked: [],
  sortable: false,
  onSort: function onSort() {},
  locale: zhCN.Transfer
});

export default config(Transfer);