import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { deepCopy } from 'amos-tool';
import { Table } from 'amos-antd';
import { tools } from '@gm/graphmod-utils';
import ImageConsts from '@gm/graphmod-assets';
import Search from './../search';
import ContextMenu from './../contextMenu';
import './TreeMgmt.scss';
/**
 * 分类树管理组件
 *
 * @class TreeMgmt
 * @extends {Component}
 */
class TreeMgmt extends Component {

  static propTypes = {
    activeKey: PropTypes.any, // 单击选择的分类
    onSelect: PropTypes.func, // 单击选择的分类的事件
    contextMenu: PropTypes.func, // 分类树上的右键菜单函数
    rowKey: PropTypes.string, // 唯一值属性名
    rowName: PropTypes.string, // 显示名称属性名
    openIcon: PropTypes.any, // 树展开左侧图标
    closeIcon: PropTypes.any, // 树合并左侧图标
    iconRender: PropTypes.func, // 动态设置树展开和合并图标渲染函数
    treeData: PropTypes.array, // 分类树数据
    addButton: PropTypes.node, // 搜索框右侧的添加分类按钮
    onSearchChange: PropTypes.func, // 搜索事件
    searchValue: PropTypes.string, // 搜索值
    placeholder: PropTypes.string,
    listClassName: PropTypes.string,
    noBlurSearch: PropTypes.bool,
    highlightList: PropTypes.array, // 高亮集合
    renderTitle: PropTypes.func, // 设置显示名称函数
    expandedRows: PropTypes.array, // 展开的行
    onExpandedRowsChange: PropTypes.func, // 展开的行
    showSearch: PropTypes.bool // 是否展示搜索
  };

  static defaultProps = {
    rowKey: 'id',
    rowName: 'name',
    openIcon: ImageConsts.common.folderOpen,
    closeIcon: ImageConsts.common.folderClose,
    treeData: [],
    highlightList: [],
    onSearchChange() { },
    onSelect() { },
    onExpandedRowsChange() { },
    contextMenu() {
      return null;
    }
  };

  constructor(props) {
    super(props);
    this.state = {
    };
  }

  setIconRender = (isOpen, record) => {
    const { openIcon, closeIcon, iconRender } = this.props;
    const img = iconRender(isOpen, record);
    if (img) {
      return img;
    } else {
      return isOpen ? openIcon : closeIcon;
    }
  }

  handleSelect = (record, isOpen) => {
    const { activeKey, onSelect, onExpandedRowsChange, rowKey, expandedRows } = this.props;
    activeKey !== record[rowKey] ? onSelect(record) : '';
    if (expandedRows.find(e => e === record[rowKey])) {
      onExpandedRowsChange(expandedRows.filter(e => e !== record[rowKey]));
    } else {
      expandedRows.push(record[rowKey]);
      onExpandedRowsChange(expandedRows);
    }
  }

  renderColumns = () => {
    const { contextMenu, rowKey, renderTitle, rowName, openIcon, closeIcon, iconRender, expandedRows } = this.props;

    return [{
      title: 'name',
      key: 'name',
      render: (text, record, index) => {
        const isOpen = expandedRows.some(e => e === record[rowKey]);
        const title = renderTitle ? renderTitle(record) : record[rowName];
        return (
          <ContextMenu
            menu={contextMenu(record)}
            onClick={() => this.handleSelect(record, isOpen)}
            style={{ display: record.hide ? 'none' : 'flex' }}
            title={title}
            className={classnames('mods-com-tree-mgmt-item')}
          >
            <div className="mods-com-tree-mgmt-item-img">
              <img src={iconRender ? this.setIconRender(isOpen, record) : isOpen ? openIcon : closeIcon} alt="" />
            </div>
            <span>{title}</span>
          </ContextMenu>
        );
      }
    }];
  }

  render() {
    const { expandedRows, noBlurSearch, activeKey, placeholder, treeData, showSearch, onSearchChange,
      highlightList, searchValue,
      addButton, rowKey, onExpandedRowsChange, listClassName } = this.props;
    return (
      <div className="mods-com-tree-mgmt">
        {
          showSearch &&
          <div className={classnames('mods-com-tree-mgmt-search', { 'mods-com-tree-mgmt-search-no-add': !addButton })}>
            <Search
              onSearch={onSearchChange}
              noBlurSearch={noBlurSearch}
              placeholder={placeholder}
              value={searchValue}
            />
            {addButton}
          </div>
        }
        <div className={`mods-com-tree-mgmt-content ${listClassName || ''}`} >
          <Table
            className="mods-com-tree-mgmt-tree"
            rowClassName={(record) => {
              let highlightClass = '';
              if (highlightList.some(e => record[rowKey] === e)) {
                highlightClass = 'mods-com-tree-mgmt-item-heightlight';
              }
              return record[rowKey] === activeKey ? `mods-com-tree-mgmt-item-select ${highlightClass}` : highlightClass;
            }}
            dataSource={treeData}
            pagination={false}
            columns={this.renderColumns()}
            rowKey={rowKey}
            size="small"
            expandedRowKeys={expandedRows}
            onExpandedRowsChange={(e) => this.setState({ expandedRows: e }, () => onExpandedRowsChange(this.state.expandedRows))}
            indentSize={15}
          />
        </div>
      </div >
    );
  }
}

TreeMgmt.resetHistory = (treeList, rowKey, activeHistory, historyActive) => {
  historyActive = historyActive.filter((e, index) => {
    if (!tools.recursive(treeList).find(d => d[rowKey] === e[rowKey])) {
      if (index < activeHistory) {
        activeHistory = activeHistory - 1;
      }
      return false;
    } else {
      return true;
    }
  });
  return { activeHistory, historyActive };
};
/**
 * 处理页面前进或后退
 */
TreeMgmt.treeBack = (treeData, rowKey, activeHistory, historyActive) => {
  const func = (index, list) => {
    const data = list[index - 1];
    if (tools.recursive(treeData).find(e => e[rowKey] === data[rowKey])) {
      return { index, list };
    } else {
      list.splice(index - 1, 1);
      index = index - 1;
      return func(index, list);
    }
  };
  activeHistory = activeHistory - 1;
  const { index, list } = func(activeHistory, historyActive);
  return { activeHistory, selectData: list[index - 1], historyActive };
};

TreeMgmt.treeForward = (treeData, rowKey, activeHistory, historyActive) => {
  const func = (index, list) => {
    const data = list[index - 1];
    if (tools.recursive(treeData).find(e => e[rowKey] === data[rowKey])) {
      return { index, list };
    } else {
      list.splice(index - 1, 1);
      return func(index, list);
    }
  };
  activeHistory = activeHistory + 1;
  const { index, list } = func(activeHistory, historyActive);
  return { activeHistory, selectData: list[index - 1], historyActive };
};

TreeMgmt.getSearchData = (searchValue, list, name, noSearchData, key, expandedRows, getExpand) => {
  list = deepCopy(list);
  if (!searchValue || !searchValue.trim()) {
    return { searchData: list, expandedRows };
  }
  const searchData = tools.recursive(list).search(d => {
    if (noSearchData.some(e => e === d[key])) {
      return true;
    }
    if (d[name].includes(searchValue)) {
      return true;
    }
  });
  const res = [];
  if (getExpand) {
    tools.recursive(list).map(e => {
      res.push(e[key]);
      return e;
    });
  }
  return { searchData, expandedRows: res };
};

export default TreeMgmt;
