import React, { FC, useState, useEffect } from 'react';
import { TableBasic } from './TableBasic';
import { TableProps } from './TableTypes';
import { TablePagination } from './TablePagination';
import { Box } from '../Box';

export const TableSubset: FC<TableProps> = ({
  data: dataProp,
  fetchData,
  pageSize = 10,
  pageSizes,
  canSkip,
  resetOn,
  ...tableProps
}) => {
  const [isLoading, setIsLoading] = useState(true);
  const [lastUpdate, setLastUpdate] = useState(new Date().toLocaleString());

  const [currentData, setCurrentData] = useState<any>([]);
  const [canPreviousPage, setCanPreviousPage] = useState(false);
  const [canNextPage, setCanNextPage] = useState(true);
  const [currentPageIndex, setCurrentPageIndex] = useState(0);
  const [pageStart, setPageStart] = useState(currentPageIndex * pageSize);
  const [dataCount, setDataCount] = useState(0);
  const getPageCount = (count: number) => Math.ceil(count / pageSize);

  const goToPage = (targetPage: number) => {
    setCurrentPageIndex(targetPage);
    setPageStart(targetPage * pageSize);
    if (targetPage === 0) {
      setCanPreviousPage(false);
      setCanNextPage(true);
    } else {
      setCanPreviousPage(true);
    }
  };

  const previousPage = () => {
    goToPage(currentPageIndex - 1);
    setCanNextPage(true);
  };

  const nextPage = () => {
    goToPage(currentPageIndex + 1);
  };

  const setTableState = (newData: any) => {
    const { data, count, next } = newData;
    if (data) setCurrentData(data);
    if (count) setDataCount(count);
    setCanNextPage(next !== null);
  };

  const getData = async (start: number) => {
    setIsLoading(true);
    const fetchResult = await fetchData({ start });
    if (!dataProp) setTableState(fetchResult);
    setIsLoading(false);
  };

  const refresh = () => {
    getData(pageStart);
    setLastUpdate(new Date().toLocaleString());
  };

  const reset = () => {
    setDataCount(0);
    setCurrentPageIndex(0);
    setCanPreviousPage(false);
    setCanNextPage(false);
    setCurrentData([]);
    setLastUpdate(new Date().toLocaleString());
    if (pageStart > 0) setPageStart(0);
    else getData(0);
  };

  useEffect(() => {
    getData(pageStart);
  }, [pageStart]); // eslint-disable-line

  useEffect(() => {
    if (resetOn) reset();
  }, [resetOn]); // eslint-disable-line

  const paginationProps = {
    canPreviousPage,
    canNextPage: dataProp ? dataProp.next !== null : canNextPage,
    gotoPage: goToPage,
    nextPage,
    previousPage,
    totalRows: dataProp ? dataProp.count : dataCount,
    pageIndex: currentPageIndex,
    pageSize,
    pageSizes,
    pageCount: dataProp
      ? getPageCount(dataProp.count)
      : getPageCount(dataCount),
    canSkip,
  };

  return (
    <>
      <TableBasic
        data={dataProp ? dataProp.data : currentData}
        refresh={refresh}
        lastUpdate={lastUpdate}
        isLoading={isLoading}
        {...tableProps}
      />
      {!isLoading && currentData.length > 0 && (
        <Box mt="l">
          <TablePagination {...paginationProps} />
        </Box>
      )}
    </>
  );
};
