import React, { FC, useState, Fragment } from 'react';
import {
  useTable,
  useSortBy,
  useRowSelect,
  usePagination,
  useExpanded,
} from 'react-table';
import { Flex } from '../Flex';
import { Box } from '../Box';
import { Text } from '../Text';
import { IconCircled } from '../IconCircled';
import { Loading } from '../Loading';
import { TablePagination } from './TablePagination';
import { TableBatchActions } from './TableBatchActions';
import { TableProps } from './TableTypes';
import { TableEditableCell } from './TableEditableCell';
import { TableRowActions } from './TableRowActions';
import * as sc from './styles';
import { SvgAccountGroup } from '../../assets/images/icons';

export const TableBasic: FC<TableProps> = ({
  title,
  empty,
  columns,
  data = [],
  updateData,
  batchActions,
  deleteRow,
  subRow,
  defaultSort,
  sortable,
  selectable,
  pageSize: pageSizeProp,
  pageSizes,
  canSkip,
  isLoading,
  refresh,
  lastUpdate,
}) => {
  const hasData = data.length > 0;
  const paginate = pageSizeProp && pageSizeProp > 1;
  const [skipTableReset, setSkipTableReset] = useState(false);
  const [showBatchActions, setShowBatchActions] = useState(false);

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    prepareRow,
    rows,
    page,
    canPreviousPage,
    canNextPage,
    nextPage,
    previousPage,
    setPageSize,
    pageCount,
    gotoPage,
    state: { pageIndex, pageSize, selectedRowIds },
  } = useTable(
    {
      data,
      columns,
      autoResetPage: !skipTableReset,
      autoResetSortBy: !skipTableReset,
      // autoResetSelectedRows: !skipTableReset,
      initialState: {
        ...(defaultSort
          ? {
              sortBy: [
                {
                  id: defaultSort.accessor,
                  desc: defaultSort.desc || false,
                },
              ],
            }
          : {}),
        pageIndex: 0,
        ...(paginate ? { pageSize: pageSizeProp } : {}),
      },
    } as any,
    useSortBy,
    useExpanded,
    usePagination,
    useRowSelect,
    (hooks: any) =>
      TableRowActions({
        hooks,
        selectable,
        setShowBatchActions,
        deleteRow,
        subRow,
        setSkipTableReset,
      })
  ) as any;

  const selectedRowIndices = Object.keys(selectedRowIds);
  const totalSelectedRows = selectedRowIndices.length;
  const selectedData = data.filter((entry: any, index: number) =>
    selectedRowIndices.includes(`${index}`)
  );

  return (
    <sc.TableWrapper>
      {(title || (!!batchActions && batchActions.length > 0)) && (
        <Flex justifyContent="space-between" p="s">
          <Box lineHeight="50px">{title}</Box>
          <Box>
            {!isLoading && !!batchActions && batchActions.length > 0 && (
              <TableBatchActions
                batchActions={batchActions}
                showBatchActions={showBatchActions}
                totalSelectedRows={totalSelectedRows}
                selectedData={selectedData}
                selectedRowIndices={selectedRowIndices}
                refresh={refresh}
                lastUpdate={lastUpdate}
              />
            )}
          </Box>
        </Flex>
      )}

      {isLoading ? (
        <Flex justifyContent="center" my="l">
          <Loading />
        </Flex>
      ) : hasData ? (
        <sc.Table {...getTableProps()}>
          <sc.TableHeader>
            {headerGroups.map((headerGroup: any, rowIndex: number) => (
              <sc.TableRow
                key={`headerRow${rowIndex}`}
                {...headerGroup.getHeaderGroupProps()}
                {...(rowIndex === 0 ? { className: 'hide' } : {})}
              >
                {headerGroup.headers.map((column: any, colIndex: number) => (
                  <sc.TableColumnHeader
                    key={`headerRow${rowIndex}Column${colIndex}`}
                    {...column.getHeaderProps(
                      sortable ? column.getSortByToggleProps() : undefined
                    )}
                    {...(column.getCustomHeaderProperties &&
                      column.getCustomHeaderProperties(rowIndex))}
                  >
                    <Text
                      variant="b2m"
                      color={column.isSorted ? 'brandMain' : 'gray.2'}
                    >
                      {column.render('Header')}
                      <span
                        dangerouslySetInnerHTML={{
                          __html: column.isSorted
                            ? column.isSortedDesc
                              ? ' &darr;'
                              : ' &uarr;'
                            : '',
                        }}
                      />
                    </Text>
                  </sc.TableColumnHeader>
                ))}
              </sc.TableRow>
            ))}
          </sc.TableHeader>
          <sc.TableBody {...getTableBodyProps()}>
            {(paginate ? page : rows).map((row: any, rowIndex: number) => {
              prepareRow(row);
              return (
                <Fragment key={`bodyRow${rowIndex}fragment`}>
                  <sc.TableRow
                    key={`bodyRow${rowIndex}`}
                    {...row.getRowProps()}
                    {...(row.isSelected ? { className: 'selected' } : {})}
                  >
                    {row.cells.map((cell: any, colIndex: number) => {
                      return (
                        <sc.TableColumn
                          key={`bodyRow${rowIndex}Column${colIndex}`}
                          {...{
                            ...cell.getCellProps(),
                            ...(cell.column.getCustomCellProperties &&
                              cell.column.getCustomCellProperties(rowIndex)),
                          }}
                          {...(cell.column.width
                            ? { width: cell.column.width }
                            : {})}
                          {...(cell.column.cellTextAlign
                            ? { textAlign: cell.column.cellTextAlign }
                            : {})}
                        >
                          {cell.column.id === 'selection' ||
                          cell.column.id === 'deletion' ? (
                            cell.render('Cell')
                          ) : (
                            <TableEditableCell
                              cell={cell}
                              data={data}
                              updateData={updateData}
                              setSkipTableReset={setSkipTableReset}
                            />
                          )}
                        </sc.TableColumn>
                      );
                    })}
                  </sc.TableRow>
                  {subRow && row.isExpanded && (
                    <sc.TableRow key={`bodyRow${rowIndex}subRow`}>
                      <sc.TableColumn colSpan={row.cells.length}>
                        {subRow(row.original, row.index) as any}
                      </sc.TableColumn>
                    </sc.TableRow>
                  )}
                </Fragment>
              );
            })}
          </sc.TableBody>
        </sc.Table>
      ) : (
        <Flex justifyContent="center" flexDirection="column" mt="l" mb="m">
          {empty && empty.icon === false
            ? null
            : (empty && empty.icon) || (
                <IconCircled
                  Asset={SvgAccountGroup}
                  bg="gray.4"
                  color="gray.3"
                  width={48}
                  height={48}
                  scale={0.8}
                />
              )}
          {empty && empty.copy === false
            ? null
            : (empty && empty.copy) || (
                <Text fontSize="2" color="gray.2" mt="m">
                  No data
                </Text>
              )}
        </Flex>
      )}

      {hasData && paginate && (
        <TablePagination
          canPreviousPage={canPreviousPage}
          canNextPage={canNextPage}
          nextPage={nextPage}
          previousPage={previousPage}
          setPageSize={setPageSize}
          totalRows={rows.length}
          pageIndex={pageIndex}
          pageSize={pageSize}
          pageSizes={pageSizes}
          {...(canSkip
            ? {
                pageCount,
                gotoPage,
              }
            : {})}
        />
      )}
    </sc.TableWrapper>
  );
};
