import { Table, Thead, Tbody, Tr, Th, Td, chakra, VStack, Flex, Image, Spinner } from '@chakra-ui/react';
import { TriangleDownIcon, TriangleUpIcon } from '@chakra-ui/icons';
import { useReactTable, flexRender, getCoreRowModel, getSortedRowModel } from '@tanstack/react-table';
import { Text } from '@chakra-ui/react';
import propTypes from 'prop-types';

import Pagination from './Pagination';

DataTable.propTypes = {
  data: propTypes.array.isRequired,
  columns: propTypes.array.isRequired,
  loading: propTypes.bool,
  order: propTypes.shape({
    id: propTypes.string.isRequired,
    desc: propTypes.bool.isRequired,
    onOrderBy: propTypes.func.isRequired,
  }),
  pagination: propTypes.shape({
    currentPage: propTypes.number.isRequired,
    pageSize: propTypes.number.isRequired,
    total: propTypes.number.isRequired,
    onPaginationChange: propTypes.func.isRequired,
  }).isRequired,
};

// Give our default column cell renderer editing superpowers!

function DataTable({ order, data, columns, pagination, loading }) {
  const table = useReactTable({
    columns,
    data,
    getCoreRowModel: getCoreRowModel(),
    onSortingChange: (func) => {
      const sorting = func()[0];
      order.onOrderBy(sorting);
    },
    getSortedRowModel: getSortedRowModel(),
    enableColumnResizing: true,
  });
  const { total, pageSize, currentPage, onPaginationChange } = pagination;
  const indexOfLastRow = currentPage * pageSize;
  const indexOfFirstRow = indexOfLastRow - pageSize;
  // const isUsingApiPagination = data?.length !== total;
  const isUsingApiPagination = true;
  let currentRows = table.getRowModel().rows;
  currentRows = isUsingApiPagination ? currentRows : currentRows.slice(indexOfFirstRow, indexOfLastRow);

  return (
    <VStack my={5} alignItems="flex-start" gap={5}>
      <Text visibility={loading ? 'hidden' : 'visible'} color="gray" fontSize="-moz-initial">
        Total rows: {total || 0}
      </Text>
      <Table variant="striped" colorScheme="primary">
        <Thead>
          {table.getHeaderGroups().map((headerGroup) => (
            <Tr key={headerGroup.id}>
              {headerGroup.headers.map((header) => {
                // see https://tanstack.com/table/v8/docs/api/core/column-def#meta to type this correctly
                const meta = header.column.columnDef.meta;
                return (
                  <Th
                    textAlign="center"
                    key={header.id}
                    onClick={header.column.getToggleSortingHandler()}
                    isNumeric={meta?.isNumeric}
                    width={header.getSize()}
                    textTransform="inherit"
                  >
                    {flexRender(header.column.columnDef.header, header.getContext())}
                    <chakra.span pl="4">
                      {header.column.columnDef.accessorKey == order?.id ? (
                        order?.desc ? (
                          <TriangleDownIcon aria-label="sorted descending" />
                        ) : (
                          <TriangleUpIcon aria-label="sorted ascending" />
                        )
                      ) : null}
                    </chakra.span>
                  </Th>
                );
              })}
            </Tr>
          ))}
        </Thead>
        {!loading && (
          <Tbody>
            {currentRows.map((row) => (
              <Tr key={row.id} textAlign="center">
                {row.getVisibleCells().map((cell) => {
                  // see https://tanstack.com/table/v8/docs/api/core/column-def#meta to type this correctly
                  const meta = cell.column.columnDef.meta;
                  return (
                    <Td opacity={loading ? '0.5' : '0.7'} textAlign="center" key={cell.id} isNumeric={meta?.isNumeric}>
                      {flexRender(cell.column.columnDef.cell, cell.getContext())}
                    </Td>
                  );
                })}
              </Tr>
            ))}
          </Tbody>
        )}
      </Table>
      {data?.length == 0 && (
        <Flex
          display={loading ? 'none' : 'flex'}
          flexDir="column"
          justifyContent="center"
          mt="10"
          alignItems="center"
          width="full"
        >
          <Image height="100px" src="/no-content.png" />
          <Text>No Data In Table</Text>
        </Flex>
      )}
      {loading && (
        <Flex flexDir="column" justifyContent="center" alignItems="center" width="full" gap={5}>
          <Spinner />
          <Text>Loading...</Text>
        </Flex>
      )}
      <Pagination currentPage={currentPage} total={total} pageSize={pageSize} onPaginationChange={onPaginationChange} />
    </VStack>
  );
}

export default DataTable;
