import React, { useMemo } from 'react';
import { Spin, Empty } from 'antd';
import style from './index.less';

const CustomTable = props => {
  const {
    columns,
    dataSource,
    rowKey,
    bordered,
    eachRowHeadRender = null,
    subDataField = null,
    loading = null,
    align = 'left',
  } = props;
  const colLength = columns.length;

  const baseColumns = useMemo(() => columns, [columns]);
  const baseDataSource = useMemo(() => dataSource, [dataSource]);

  const ColElement = () =>
    baseColumns.map((column, index) => {
      const key = column.dataIndex || index.toString();
      const styleWidth = column.width ? { width: column.width } : {};
      return <col key={key} style={styleWidth}></col>;
    });

  /** @name thead内容 */
  const TheadElement = () => (
    <tr>
      {baseColumns.map((column, index) => {
        const key = column.dataIndex || index;
        return <th key={key}>{column.title}</th>;
      })}
    </tr>
  );

  /** @name 获取td元素数据 */
  const getTdElement = ({ dataSourceItem, dataSourceIndex, subData, subDataItem, subDataIndex }) =>
    baseColumns.map((column, index) => {
      const { render, dataIndex, align: itemAlign = null } = column;
      const key = dataIndex || index;
      // 子集不存在的属性去顶级查找
      const currentData =
        subDataItem && subDataItem[key] !== undefined ? subDataItem[key] : dataSourceItem[key];

      let rowSpan = 1;
      // 设置了自动合并 && 只设置第一条数据的值，其他的返回<></>
      if (column.rowSpanMode === 'auto' && subData) {
        rowSpan = subData.length;
        if (subDataIndex > 0) {
          return <></>;
        }
      }

      const renderParams = {
        value: currentData,
        record: dataSourceItem,
        index: dataSourceIndex,
        subRecord: subDataItem,
        subIndex: subDataIndex,
      };
      return (
        <td rowSpan={rowSpan} key={key} align={itemAlign || align}>
          <div className={style['td-box']}>{render ? render(renderParams) : currentData}</div>
        </td>
      );
    });

  /** @name 每一行的头部自定义渲染 */
  const EachRowHeadElement = dataSourceItem => (
    <tr>
      <td className={style['thead-render']} colSpan={colLength}>
        {' '}
        {eachRowHeadRender(dataSourceItem)}
      </td>
    </tr>
  );

  /** @name tbody内容 */
  const TbodyElement = () =>
    baseDataSource.map((dataSourceItem, dataSourceIndex) => {
      const subData = subDataField ? dataSourceItem[subDataField] : dataSourceItem;
      let tbodyElement = '';
      if (Array.isArray(subData)) {
        tbodyElement = subData.map((subDataItem, subDataIndex) => {
          const key = subDataItem[rowKey] || subDataIndex.toString();
          return (
            <tr key={key}>
              {getTdElement({
                dataSourceItem,
                dataSourceIndex,
                subData,
                subDataItem,
                subDataIndex,
              })}
            </tr>
          );
        });
      } else {
        const key = subData[rowKey] || dataSourceIndex.toString();
        tbodyElement = (
          <tr key={key}>{getTdElement({ dataSourceItem, dataSourceIndex, subData })}</tr>
        );
      }

      return (
        <React.Fragment key={dataSourceIndex.toString()}>
          {eachRowHeadRender ? (
            <EachRowHeadElement key={dataSourceIndex.toString()} {...dataSourceItem} />
          ) : (
            ''
          )}
          {tbodyElement}
        </React.Fragment>
      );
    });

  const EmptyElement = () => {
    if (!dataSource || dataSource.length === 0) {
      return (
        <div className={style['custom-table-empty']}>
          <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
        </div>
      );
    }
    return <></>;
  };
  const memoTable = useMemo(
    () => (
      <table>
        <colgroup>
          <ColElement />
        </colgroup>
        <thead className={style['custom-table-thead']}>
          <TheadElement />
        </thead>
        <tbody className={style['custom-table-tbody']}>
          <TbodyElement />
        </tbody>
      </table>
    ),
    [props.dataSource],
  );

  return (
    <div className={`${style['custom-table']} ${bordered ? style['custom-table-bordered'] : ''}`}>
      <Spin spinning={loading}>
        {memoTable}
        <EmptyElement />
      </Spin>
    </div>
  );
};

export { CustomTable };
