'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _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; };

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _rcTrigger = require('rc-trigger');

var _rcTrigger2 = _interopRequireDefault(_rcTrigger);

var _rcTree = require('rc-tree');

var _rcTree2 = _interopRequireDefault(_rcTree);

var _util = require('./util');

var _toArray = require('rc-util/lib/Children/toArray');

var _toArray2 = _interopRequireDefault(_toArray);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

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; }

var BUILT_IN_PLACEMENTS = {
  bottomLeft: {
    points: ['tl', 'bl'],
    offset: [0, 4],
    overflow: {
      adjustX: 0,
      adjustY: 1
    }
  },
  topLeft: {
    points: ['bl', 'tl'],
    offset: [0, -4],
    overflow: {
      adjustX: 0,
      adjustY: 1
    }
  }
};

var SelectTrigger = _react2["default"].createClass({
  displayName: 'SelectTrigger',

  propTypes: {
    dropdownMatchSelectWidth: _react.PropTypes.bool,
    dropdownPopupAlign: _react.PropTypes.object,
    visible: _react.PropTypes.bool,
    filterTreeNode: _react.PropTypes.any,
    treeNodes: _react.PropTypes.any,
    inputValue: _react.PropTypes.string,
    prefixCls: _react.PropTypes.string,
    popupClassName: _react.PropTypes.string,
    children: _react.PropTypes.any
  },

  getInitialState: function getInitialState() {
    return {
      _expandedKeys: [],
      fireOnExpand: false
    };
  },
  componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
    if (nextProps.inputValue && nextProps.inputValue !== this.props.inputValue) {
      // set autoExpandParent to true
      this.setState({
        _expandedKeys: [],
        fireOnExpand: false
      });
    }
  },
  componentDidUpdate: function componentDidUpdate() {
    if (this.props.dropdownMatchSelectWidth && this.props.visible) {
      var dropdownDOMNode = this.getPopupDOMNode();
      if (dropdownDOMNode) {
        dropdownDOMNode.style.width = _reactDom2["default"].findDOMNode(this).offsetWidth + 'px';
      }
    }
  },
  onExpand: function onExpand(expandedKeys) {
    // rerender
    this.setState({
      _expandedKeys: expandedKeys,
      fireOnExpand: true
    });
  },
  getPopupEleRefs: function getPopupEleRefs() {
    return this.popupEle && this.popupEle.refs;
  },
  getPopupDOMNode: function getPopupDOMNode() {
    return this.refs.trigger.getPopupDomNode();
  },
  getDropdownTransitionName: function getDropdownTransitionName() {
    var props = this.props;
    var transitionName = props.transitionName;
    if (!transitionName && props.animation) {
      transitionName = this.getDropdownPrefixCls() + '-' + props.animation;
    }
    return transitionName;
  },
  getDropdownPrefixCls: function getDropdownPrefixCls() {
    return this.props.prefixCls + '-dropdown';
  },
  highlightTreeNode: function highlightTreeNode(treeNode) {
    var props = this.props;
    var filterVal = treeNode.props[(0, _util.labelCompatible)(props.treeNodeFilterProp)];
    if (typeof filterVal === 'string') {
      return props.inputValue && filterVal.indexOf(props.inputValue) > -1;
    }
    return false;
  },
  filterTreeNode: function filterTreeNode(input, child) {
    if (!input) {
      return true;
    }
    var filterTreeNode = this.props.filterTreeNode;
    if (!filterTreeNode) {
      return true;
    }
    if (child.props.disabled) {
      return false;
    }
    return filterTreeNode.call(this, input, child);
  },
  savePopupElement: function savePopupElement(ele) {
    this.popupEle = ele;
  },
  processTreeNode: function processTreeNode(treeNodes) {
    var _this = this;

    var filterPoss = [];
    this._expandedKeys = [];
    (0, _util.loopAllChildren)(treeNodes, function (child, index, pos) {
      if (_this.filterTreeNode(_this.props.inputValue, child)) {
        filterPoss.push(pos);
        _this._expandedKeys.push(child.key);
      }
    });

    // Include the filtered nodes's ancestral nodes.
    var processedPoss = [];
    filterPoss.forEach(function (pos) {
      var arr = pos.split('-');
      arr.reduce(function (pre, cur) {
        var res = pre + '-' + cur;
        if (processedPoss.indexOf(res) < 0) {
          processedPoss.push(res);
        }
        return res;
      });
    });
    var filterNodesPositions = [];
    (0, _util.loopAllChildren)(treeNodes, function (child, index, pos) {
      if (processedPoss.indexOf(pos) > -1) {
        filterNodesPositions.push({ node: child, pos: pos });
      }
    });

    var hierarchyNodes = (0, _util.flatToHierarchy)(filterNodesPositions);

    var recursive = function recursive(children) {
      return children.map(function (child) {
        if (child.children) {
          return _react2["default"].cloneElement(child.node, {}, recursive(child.children));
        }
        return child.node;
      });
    };
    return recursive(hierarchyNodes);
  },
  renderTree: function renderTree(keys, halfCheckedKeys, newTreeNodes, multiple) {
    var props = this.props;

    var trProps = {
      multiple: multiple,
      prefixCls: props.prefixCls + '-tree',
      showIcon: props.treeIcon,
      showLine: props.treeLine,
      defaultExpandAll: props.treeDefaultExpandAll,
      defaultExpandedKeys: props.treeDefaultExpandedKeys,
      filterTreeNode: this.highlightTreeNode
    };

    if (props.treeCheckable) {
      trProps.selectable = false;
      trProps.checkable = props.treeCheckable;
      trProps.onCheck = props.onSelect;
      trProps.checkStrictly = props.treeCheckStrictly;
      if (props.inputValue) {
        // enable checkStrictly when search tree.
        trProps.checkStrictly = true;
      } else {
        trProps._treeNodesStates = props._treeNodesStates;
      }
      if (trProps.treeCheckStrictly && halfCheckedKeys.length) {
        trProps.checkedKeys = { checked: keys, halfChecked: halfCheckedKeys };
      } else {
        trProps.checkedKeys = keys;
      }
    } else {
      trProps.selectedKeys = keys;
      trProps.onSelect = props.onSelect;
    }

    // expand keys
    if (!trProps.defaultExpandAll && !trProps.defaultExpandedKeys && !props.loadData) {
      trProps.expandedKeys = keys;
    }
    trProps.autoExpandParent = true;
    trProps.onExpand = this.onExpand;
    if (this._expandedKeys && this._expandedKeys.length) {
      trProps.expandedKeys = this._expandedKeys;
    }
    if (this.state.fireOnExpand) {
      trProps.expandedKeys = this.state._expandedKeys;
      trProps.autoExpandParent = false;
    }

    // async loadData
    if (props.loadData) {
      trProps.loadData = props.loadData;
    }

    return _react2["default"].createElement(
      _rcTree2["default"],
      _extends({ ref: this.savePopupElement }, trProps),
      newTreeNodes
    );
  },
  render: function render() {
    var _popupClassName;

    var props = this.props;
    var multiple = props.multiple;
    var dropdownPrefixCls = this.getDropdownPrefixCls();
    var popupClassName = (_popupClassName = {}, _defineProperty(_popupClassName, props.dropdownClassName, !!props.dropdownClassName), _defineProperty(_popupClassName, dropdownPrefixCls + '--' + (multiple ? 'multiple' : 'single'), 1), _popupClassName);
    var visible = props.visible;
    var search = multiple || props.combobox || !props.showSearch ? null : _react2["default"].createElement(
      'span',
      { className: dropdownPrefixCls + '-search' },
      props.inputElement
    );

    var recursive = function recursive(children) {
      // Note: if use `React.Children.map`, the node's key will be modified.
      return (0, _toArray2["default"])(children).map(function handler(child) {
        // eslint-disable-line
        if (child && child.props.children) {
          // null or String has no Prop
          return _react2["default"].createElement(
            _rcTree.TreeNode,
            _extends({}, child.props, { key: child.key }),
            recursive(child.props.children)
          );
        }
        return _react2["default"].createElement(_rcTree.TreeNode, _extends({}, child.props, { key: child.key }));
      });
    };
    // const s = Date.now();
    var treeNodes = void 0;
    if (props._cachetreeData && this.treeNodes) {
      treeNodes = this.treeNodes;
    } else {
      treeNodes = recursive(props.treeData || props.treeNodes);
      this.treeNodes = treeNodes;
    }
    // console.log(Date.now()-s);

    if (props.inputValue) {
      treeNodes = this.processTreeNode(treeNodes);
    }

    var keys = [];
    var halfCheckedKeys = [];
    (0, _util.loopAllChildren)(treeNodes, function (child) {
      if (props.value.some(function (item) {
        return item.value === (0, _util.getValuePropValue)(child);
      })) {
        keys.push(child.key);
      }
      if (props.halfCheckedValues && props.halfCheckedValues.some(function (item) {
        return item.value === (0, _util.getValuePropValue)(child);
      })) {
        halfCheckedKeys.push(child.key);
      }
    });

    var notFoundContent = void 0;
    if (!treeNodes.length) {
      if (props.notFoundContent) {
        notFoundContent = _react2["default"].createElement(
          'span',
          { className: props.prefixCls + '-not-found' },
          props.notFoundContent
        );
      } else if (!search) {
        visible = false;
      }
    }
    var popupElement = _react2["default"].createElement(
      'div',
      null,
      search,
      notFoundContent || this.renderTree(keys, halfCheckedKeys, treeNodes, multiple)
    );

    return _react2["default"].createElement(
      _rcTrigger2["default"],
      {
        action: props.disabled ? [] : ['click'],
        ref: 'trigger',
        popupPlacement: 'bottomLeft',
        builtinPlacements: BUILT_IN_PLACEMENTS,
        popupAlign: props.dropdownPopupAlign,
        prefixCls: dropdownPrefixCls,
        popupTransitionName: this.getDropdownTransitionName(),
        onPopupVisibleChange: props.onDropdownVisibleChange,
        popup: popupElement,
        popupVisible: visible,
        getPopupContainer: props.getPopupContainer,
        popupClassName: (0, _classnames2["default"])(popupClassName),
        popupStyle: props.dropdownStyle
      },
      this.props.children
    );
  }
});

exports["default"] = SelectTrigger;
module.exports = exports['default'];