import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Table from './Table';
import classnames from 'classnames';
// @require '../style/collapse_table.scss'

const CollapseTriangleIndex = 0;

/**
 * 可折叠行表格
 */
export default class CollapseTable extends Component {

  static propTypes = {
    style: PropTypes.object,
    className: PropTypes.string,
    /**
     * 透传给Table组件的属性
     */
    tableProps: PropTypes.shape(Table.propTypes),
    /**
     * 配置每列表头
     */
    cols: PropTypes.arrayOf(PropTypes.shape({
      /**
       * 表格头部一列名称
       */
      display: PropTypes.any.isRequired,
      /**
       * 表格一列所占宽度百分比
       */
      width: PropTypes.number,
      /**
       * 跨列
       * 默认为1
       */
      colspan: PropTypes.number,
    })),
    /**
     * 表格体的数据
     * 一维数组
     */
    data: PropTypes.arrayOf(PropTypes.shape({
      /**
       * 一维数组，当前一行需要的数据。该行会一直显示，通过点击来控制是否显示对应被控制的折叠的行是否显示
       * 如果数组元素是
       * React组件实例：展示元素本身
       * else：展示元素toString()
       * 如果数组元素是空字符串或者==null会显示为'-'
       */
      row: PropTypes.array.isRequired,
      /**
       * 当前这行控制的可以被折叠的行
       * 二维数组
       * 如果数组元素是
       * React组件实例：展示元素本身
       * else：展示元素toString()
       * 如果数组元素是空字符串或者==null会显示为'-'
       */
      collapseRows: PropTypes.arrayOf(PropTypes.array),
      /**
       * 是否显示
       * 当前这行控制的可以被折叠的行
       * 默认为false
       */
      showCollapseRows: PropTypes.bool,
    })),
    /**
     * 悬浮展示在表格的正中间
     */
    overlap: PropTypes.any,
  };

  static defaultProps = {
    data: [],
  };

  constructor(props) {
    super(props);
    this.state = {
      /**
       * 用于传给Table组件的data
       */
      tableData: this.data2TableData(props.data),
    };
  }

  componentWillReceiveProps(nextProps) {
    this.setState({
      tableData: this.data2TableData(nextProps.data),
    });
  }

  /**
   * 把通过属性传过来的data转换为Table组件需要的data
   * @param data
   * @returns {Array}
   */
  data2TableData = (data) => {
    let tableData = [];
    if (Array.isArray(data)) {
      data.forEach((one) => {
        let { row, collapseRows, showCollapseRows } = one;
        if (Array.isArray(collapseRows)) {
          row.collapseRows = collapseRows;
          if (showCollapseRows == null) {
            showCollapseRows = false;
          }
          // 注入三角形
          row[CollapseTriangleIndex] = (
            <div>
              {row[CollapseTriangleIndex]}
              <div className="im-collapse-table-triangle"></div>
              <div className="im-collapse-table-triangle-inner"></div>
            </div>
          );
          row.showCollapseRows = showCollapseRows;
          row.style = {
            cursor: 'pointer',
          };
        }
        row.className = classnames('im-collapse-table-toggle-row', {
          'im-collapse-table-toggle-row-open': showCollapseRows,
          'im-collapse-table-toggle-row-closed': !showCollapseRows,
        });
        tableData.push(row);
        if (Array.isArray(collapseRows)) {
          collapseRows.forEach(collapseRow => {
            collapseRow.className = 'im-collapse-table-collapse-row';
            if (row.showCollapseRows) {
              tableData.push(collapseRow);
            }
          });
        }
      });
    }
    return tableData;
  }

  /**
   * 开关当前这行控制的可以被折叠的行
   * @param row
   */
  toggle = (row) => {
    const { collapseRows, showCollapseRows } = row;
    const { tableData } = this.state;
    const { onRowClick } = this.props;

    if (Array.isArray(collapseRows)) {
      let index = -1;
      for (let i = 0; i < tableData.length; i++) {
        let tableRow = tableData[i];
        if (tableRow === row) {
          index = i;
          break;
        }
      }
      if (index >= 0) {
        if (showCollapseRows) {
          // 隐藏CollapseRows
          tableData.splice(index + 1, collapseRows.length);
        } else {
          // 显示CollapseRows
          tableData.splice.apply(tableData, [index + 1, 0].concat(collapseRows));
        }
        row.showCollapseRows = !showCollapseRows;
        row.className = classnames('im-collapse-table-toggle-row', {
          'im-collapse-table-toggle-row-active': showCollapseRows,
          'im-collapse-table-toggle-row-open': !showCollapseRows,
          'im-collapse-table-toggle-row-closed': showCollapseRows,
        });
        if (onRowClick) {
          onRowClick(index, tableData[index], {
            propsData: this.props.data,
          });
        }
        this.setState({
          tableData,
        });
      }
    }
  }

  render() {
    const { className, style, tableProps, cols, overlap } = this.props;
    const { tableData } = this.state;
    return (
      <Table
        {...tableProps}
        className={classnames('im-collapse-table', className)}
        style={style}
        differentiateRow={false}
        cols={cols}
        data={tableData}
        onRowClick={this.toggle}
        overlap={overlap}
      />
    );
  }
}
