import { TriangleDownIcon, TriangleUpIcon } from '@chakra-ui/icons'
import { chakra, Table, TableContainer, Tbody, Td, Th, Thead, Tr } from '@chakra-ui/react'
import { flexRender, getCoreRowModel, getSortedRowModel, SortingState, useReactTable } from '@tanstack/react-table'
import { AnimatePresence, motion } from 'framer-motion'
import React, { useEffect } from 'react'
import { CustomColumnDef } from './types'
// import { useSticky } from 'react-table-sticky'

export type DataTableProps<Data extends object> = {
  data: Data[]
  columns: CustomColumnDef<Data, any>[]
}

export function DataTable<Data extends object>({ data, columns }: DataTableProps<Data>) {
  const [sorting, setSorting] = React.useState<SortingState>([])
  const [columnVisibility, setColumnVisibility] = React.useState<any>({})

  useEffect(() => {
    const visibleObject = {}
    for (let col of columns) {
      visibleObject[(col as any)?.accessorKey] = col?.isHidden ? false : true
    }
    setColumnVisibility(visibleObject)
  }, [columns])

  const table = useReactTable({
    columns,
    data,
    getCoreRowModel: getCoreRowModel(),
    onSortingChange: setSorting,
    getSortedRowModel: getSortedRowModel(),
    state: {
      sorting,
      columnVisibility,
    },
    onColumnVisibilityChange: setColumnVisibility,
  })

  return (
    <TableContainer p={5}>
      <Table variant={'primary'}>
        <Thead>
          {table.getHeaderGroups().map((headerGroup) => {
            return (
              <Tr key={headerGroup.id}>
                {headerGroup.headers.map((header) => {
                  const meta: any = header.column.columnDef.meta
                  return (
                    <Th
                      key={header.id}
                      onClick={header.column.getToggleSortingHandler()}
                      isNumeric={meta?.isNumeric}
                      cursor={'pointer'}
                    >
                      {flexRender(header.column.columnDef.header, header.getContext())}
                      <chakra.span pl="4">
                        {header.column.getIsSorted() ? (
                          header.column.getIsSorted() === 'desc' ? (
                            <TriangleDownIcon aria-label="sorted descending" />
                          ) : (
                            <TriangleUpIcon aria-label="sorted ascending" />
                          )
                        ) : null}
                      </chakra.span>
                    </Th>
                  )
                })}
              </Tr>
            )
          })}
        </Thead>
        <Tbody as={motion.tbody} animate={{ opacity: 1 }} initial={{ opacity: 0 }} layout exit={{ opacity: 0 }}>
          <AnimatePresence>
            {table.getRowModel().rows.map((row) => {
              return (
                <Tr
                  key={row.id}
                  as={motion.tr}
                  animate={{ opacity: 1 }}
                  initial={{ opacity: 0 }}
                  layout
                  exit={{ opacity: 0 }}
                >
                  {row.getVisibleCells().map((cell) => {
                    const meta: any = cell.column.columnDef.meta
                    return (
                      <Td key={cell.id} isNumeric={meta?.isNumeric}>
                        {flexRender(cell.column.columnDef.cell, cell.getContext())}
                      </Td>
                    )
                  })}
                </Tr>
              )
            })}
          </AnimatePresence>
        </Tbody>
      </Table>
    </TableContainer>
  )
}
