import {Spin} from 'antd';
import 'antd/lib/table/style';
import {ColumnsType} from 'antd/es/table';
import {
  createPageContext,
  createSearchContext,
  usePage,
  useTableSearchState,
} from '@hooks';
import {PAGE_SIZE_LIST, calcColumnsWidth} from '@utils';
import {ReactElement, useMemo} from 'react';
import {useTable} from './hooks';
import {flexRender} from '@tanstack/react-table';
import css from './index.module.css';
import classNames from 'classnames';

type Props<T> = {
  columns: ColumnsType<T>;
  data: T[];
  pageContext: ReturnType<typeof createPageContext>;
  searchContext: ReturnType<typeof createSearchContext>;
  count: number;
  rowKey?: string;
  'data-testid'?: string;
  pageSizeList?: string[];
};

function Table<T extends Record<string, any>>(props: Props<T>): ReactElement {
  const {
    columns,
    data,
    pageContext,
    searchContext,
    count,
    rowKey,
    pageSizeList = PAGE_SIZE_LIST,
  } = props;
  const [{page, pageSize}, {onPageChange}] = usePage(pageContext);
  const [isSearching] = useTableSearchState(searchContext);
  const colWidth = calcColumnsWidth(columns);
  const scrollX = colWidth > 0 ? {x: colWidth} : void 0;

  const tableColumns = useMemo(
    function () {
      return [
        {
          title: '序号',
          width: 64,
          render(_: any, __: any, idx: number) {
            return idx + 1;
          },
          align: 'center',
        },
        ...columns,
      ];
    },
    [columns],
  );

  const {getHeaderGroups, getRowModel, getCenterTotalSize} = useTable(
    columns,
    data,
  );

  return (
    <Spin spinning={isSearching}>
      <div className={css.tableWrapper}>
        <table className={css.table} style={{width: getCenterTotalSize()}}>
          <thead className={css.tableHead}>
            {getHeaderGroups().map(function ({id, headers}) {
              return (
                <tr key={id}>
                  {headers.map(header => (
                    <th key={header.id} style={{width: header.getSize()}}>
                      {header.isPlaceholder
                        ? null
                        : flexRender(
                            header.column.columnDef.header,
                            header.getContext(),
                          )}

                      <div
                        onMouseDown={header.getResizeHandler()}
                        className={classNames(css.resizer, {
                          [css.resizing]: header.column.getIsResizing(),
                        })}
                      />
                    </th>
                  ))}
                </tr>
              );
            })}
          </thead>
          <tbody className={css.tableBody}>
            {getRowModel().rows.map(function ({id, getVisibleCells}) {
              return (
                <tr key={id}>
                  {getVisibleCells().map(function ({id, column, getContext}) {
                    return (
                      <td key={id} style={{width: column.getSize()}}>
                        {flexRender(column.columnDef.cell, getContext())}
                      </td>
                    );
                  })}
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </Spin>
  );
}

export default Table;
