import {Spin} from 'antd';
import {ColumnsType} from 'antd/es/table';
import {
  createPageContext,
  createSearchContext,
  usePage,
  useTableSearchState,
} from '@hooks';
import {PAGE_SIZE_LIST} from '@utils';
import {ReactElement} from 'react';
import {useTable} from './hooks';
import {flexRender} from '@tanstack/react-table';
import css from './index.module.css';
import HeaderTh from './header-th';

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 [
    {
      getHeaderGroups,
      getRowModel,
      getCenterTotalSize,
      setColumnOrder,
      getState,
    },
  ] = useTable(columns, data);

  return (
    <Spin spinning={isSearching}>
      <div className={css.tableWrapper} id='table_wrapper'>
        <table className={css.table} style={{width: getCenterTotalSize()}}>
          <thead className={css.tableHead}>
            {getHeaderGroups().map(function ({id, headers}) {
              return (
                <tr key={id}>
                  {headers.map(header => (
                    <HeaderTh
                      key={header.id}
                      header={header}
                      update={setColumnOrder}
                      getState={getState}
                    />
                  ))}
                </tr>
              );
            })}
          </thead>
          <tbody className={css.tableBody}>
            {getRowModel().rows.map(function ({id, getVisibleCells}) {
              return (
                <tr key={id}>
                  {getVisibleCells().map(function ({id, column, getContext}) {
                    const align =
                      (
                        column.columnDef.meta as {
                          align: 'left' | 'right' | 'center';
                        }
                      )?.align ?? 'left';
                    return (
                      <td
                        key={id}
                        style={{
                          width: column.getSize(),
                          textAlign: align,
                        }}
                      >
                        {flexRender(column.columnDef.cell, getContext())}
                      </td>
                    );
                  })}
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </Spin>
  );
}

export default Table;
