import React, { Component } from 'react';
import { Tree, Input } from 'antd';
import { connect } from 'dva';

const TreeNode = Tree.TreeNode;
const Search = Input.Search;

const stateDataKey = 'searchTreeData';

/**
 * 带有搜索功能的 Tree 组件
 */
class SearchTree extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      expandedKeys: [],
      searchValue: '',
      autoExpandParent: true,
      dataList: []
    };
  }

  componentWillMount() {
    const { dispatch, treeUrl } = this.props;
    if (!treeUrl) return;
    dispatch({
      type: "global/refTreeServer",
      payload: { url: treeUrl, key: stateDataKey }
    });
  }

  onExpand = (expandedKeys) => {
    this.setState({
      expandedKeys,
      autoExpandParent: false,
    });
  }
  onChange = (e) => {
    const value = e.target.value;
    const dataList = this.state.dataList;
    const gData = this.props.treeDatas;
    const expandedKeys = dataList.map((item) => {
      if (value && item.title.indexOf(value) > -1) {
        return this.getParentKey(item.key, gData);
      }
      return null;
    }).filter((item, i, self) => item && self.indexOf(item) === i);
    this.setState({
      expandedKeys,
      searchValue: value,
      autoExpandParent: true,
    });
  }
  getParentKey = (key, tree) => {
    let parentKey;
    for (let i = 0; i < tree.length; i++) {
      const node = tree[i];
      if (node.children) {
        if (node.children.some(item => item.key === key)) {
          parentKey = node.key;
        } else if (this.getParentKey(key, node.children)) {
          parentKey = this.getParentKey(key, node.children);
        }
      }
    }
    return parentKey;
  };
  getTreeNode = data => {
    if (!data) return;
    const { searchValue } = this.state;
    return data.map((item) => {
      item.title = item.name;
      item.key = item.id;
      item.children = item.items;
      const index = item.title.indexOf(searchValue);
      const beforeStr = item.title.substr(0, index);
      const afterStr = item.title.substr(index + searchValue.length);
      const title = index > -1 ? (
        <span>
          {beforeStr}
          <span style={{ color: '#f50' }}>{searchValue}</span>
          {afterStr}
        </span>
      ) : <span>{item.title}</span>;
      if (item.children && item.children.length > 0) {
        return (
          <TreeNode key={item.key} title={title}>
            {this.getTreeNode(item.children)}
          </TreeNode>
        );
      }
      return <TreeNode key={item.key} title={title} />;
    });
  }
  // 将结构数据拍平，用于搜索匹配后找到其父节点
  generateList = data => {
    if (!data) return;
    for (let i = 0; i < data.length; i++) {
      const node = data[i];
      const key = node.key;
      const title = node.title;
      this.state.dataList.push({ key, title });
      if (node.children) {
        this.generateList(node.children, node.key);
      }
    }
  };
  handleSelect = (selectedKeys, info) => {
    this.props.onSelect(selectedKeys, info);
  }
  // 根据出入数据字段配置，适配该组件所使用的 key、title、children 字段； 默认为：id、name、items
  transDatas(datas) {
    if (!datas) return [];
    return datas.map((item) => {
      if (this.props.treeKeyword) {
        item.key = item[this.props.treeKeyword];
      } else {
        item.key = item.id;
      }
      if (this.props.treeTitleword) {
        item.title = item[this.props.treeTitleword];
      } else {
        item.title = item.name;
      }
      if (this.props.treeChildrenword) {
        item.children = item[this.props.treeChildrenword];
      } else {
        item.children = item.items;
      }
      if (item.children) {
        this.transDatas(item.children);
      }
      return item;
    });
  }
  render() {
    const { expandedKeys, autoExpandParent } = this.state;
    let { treeDatas } = this.props;
    treeDatas = this.transDatas(treeDatas);

    this.generateList(treeDatas);
    return (
      <div>
        <Search style={{ marginBottom: 8 }} placeholder="搜索" onChange={this.onChange} />
        <Tree
          onExpand={this.onExpand}
          expandedKeys={expandedKeys}
          autoExpandParent={autoExpandParent}
          onSelect={this.handleSelect}
        >
          {this.getTreeNode(treeDatas)}
        </Tree>
      </div>
    );
  }
}
export default connect(state => ({
  ...state,
  treeDatas: state.global[stateDataKey]
}))(SearchTree);
