import { useEffect } from 'react'

import { flexRender, type Table as ITable } from '@tanstack/react-table'
import { ChevronDown, ChevronRight } from 'lucide-react'

import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table.tsx'
import { cn } from '@/lib/utils.ts'

import { Loading } from './loading.tsx'

interface Props<TData> {
  table: ITable<TData>
}

export function BaseTable<TData>({ table }: Props<TData>) {
  const pageIndex = table.getState().pagination.pageIndex
  const pageSize = table.getState().pagination.pageSize
  const rowCount = table.options.rowCount
  const currentPageRowsLength = table.getCoreRowModel().rows.length
  const isFetching = table.options.meta?.isFetching

  useEffect(() => {
    if (pageIndex > 0 && currentPageRowsLength === 0 && rowCount) {
      const lastPageIndex = Math.max(0, Math.ceil(rowCount / pageSize) - 1)
      if (lastPageIndex !== pageIndex) {
        table.setPageIndex(lastPageIndex)
        table.setPagination((prev) => ({ ...prev, pageIndex: lastPageIndex }))
      }
    }
  }, [pageIndex, currentPageRowsLength, rowCount, pageSize, table])

  const isTree = !!table.options.getExpandedRowModel

  return (
    <Loading visible={isFetching}>
      <div className='border border-border/80 rounded-md'>
        <Table>
          <TableHeader>
            {table.getHeaderGroups().map((headerGroup) => (
              <TableRow key={headerGroup.id} className='bg-muted/50'>
                {headerGroup.headers.map((header) => (
                  <TableHead
                    key={header.id}
                    className={cn(header.column.columnDef.meta?.className ?? '')}
                  >
                    {header.isPlaceholder
                      ? null
                      : flexRender(header.column.columnDef.header, header.getContext())}
                  </TableHead>
                ))}
              </TableRow>
            ))}
          </TableHeader>
          <TableBody>
            {table.getRowModel().rows?.length ? (
              table.getRowModel().rows.map((row) => (
                <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>
                  {row.getVisibleCells().map((cell, cellIndex) => (
                    <TableCell
                      key={cell.id}
                      className={cn(cell.column.columnDef.meta?.className ?? '')}
                    >
                      {cellIndex === 0 && isTree ? (
                        <div
                          className='flex items-center gap-1'
                          style={{ paddingLeft: `${row.depth * 1.25}rem` }}
                        >
                          {row.getCanExpand() ? (
                            <button
                              onClick={row.getToggleExpandedHandler()}
                              className='flex items-center justify-center w-4 h-4 shrink-0 cursor-pointer'
                            >
                              {row.getIsExpanded() ? (
                                <ChevronDown className='w-4 h-4 ' />
                              ) : (
                                <ChevronRight className='w-4 h-4 ' />
                              )}
                            </button>
                          ) : (
                            <span className='w-4 h-4 shrink-0'></span>
                          )}
                          {flexRender(cell.column.columnDef.cell, cell.getContext())}
                        </div>
                      ) : (
                        flexRender(cell.column.columnDef.cell, cell.getContext())
                      )}
                    </TableCell>
                  ))}
                </TableRow>
              ))
            ) : (
              <TableRow>
                <TableCell colSpan={table.getAllColumns().length} className='h-24 text-center'>
                  No results.
                </TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>
      </div>
    </Loading>
  )
}
