import { type Table as TanstackTable, flexRender } from '@tanstack/react-table';
import type * as React from 'react';
import {
  DataTablePagination,
  type DataTablePaginationProps
} from '@/components/ui/table/data-table-pagination';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow
} from '@/components/ui/table';
import { getCommonPinningStyles } from '@/lib/data-table';
import { cn } from '@/lib/utils';

interface DataTableProps<TData> extends React.ComponentProps<'div'> {
  table: TanstackTable<TData>;
  actionBar?: React.ReactNode;
  tableClassName?: string;
  scrollWrapperClassName?: string;
  shellClassName?: string;
  headerClassName?: string;
  headClassName?: string;
  bodyRowClassName?: string;
  bodyCellClassName?: string;
  paginationProps?: Omit<DataTablePaginationProps<TData>, 'table'>;
}

export function DataTable<TData>({
  table,
  actionBar,
  children,
  tableClassName,
  scrollWrapperClassName,
  shellClassName,
  headerClassName,
  headClassName,
  bodyRowClassName,
  bodyCellClassName,
  paginationProps
}: DataTableProps<TData>) {
  return (
    <div className='flex w-full min-w-0 max-w-full flex-1 flex-col space-y-4 overflow-hidden'>
      {children}
      <div
        className={cn(
          'w-full min-w-0 max-w-full overflow-hidden rounded-lg border',
          shellClassName
        )}
      >
        <div className={cn('w-full overflow-x-auto', scrollWrapperClassName)}>
          <Table className={cn('min-w-full', tableClassName)}>
            <TableHeader className={cn('bg-muted sticky top-0 z-10', headerClassName)}>
              {table.getHeaderGroups().map((headerGroup) => (
                <TableRow key={headerGroup.id}>
                  {headerGroup.headers.map((header) => (
                    <TableHead
                      key={header.id}
                      colSpan={header.colSpan}
                      className={cn(headClassName, header.column.columnDef.meta?.headerClassName)}
                      style={{
                        ...getCommonPinningStyles({ column: header.column })
                      }}
                    >
                      {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'}
                    className={bodyRowClassName}
                  >
                    {row.getVisibleCells().map((cell) => (
                      <TableCell
                        key={cell.id}
                        className={cn(bodyCellClassName, cell.column.columnDef.meta?.cellClassName)}
                        style={{
                          ...getCommonPinningStyles({ column: cell.column })
                        }}
                      >
                        {flexRender(cell.column.columnDef.cell, cell.getContext())}
                      </TableCell>
                    ))}
                  </TableRow>
                ))
              ) : (
                <TableRow>
                  <TableCell colSpan={table.getAllColumns().length} className='h-24 text-center'>
                    ไม่พบข้อมูล
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>
      </div>
      <div className='flex flex-col gap-2.5'>
        <DataTablePagination table={table} {...paginationProps} />
        {actionBar && table.getFilteredSelectedRowModel().rows.length > 0 && actionBar}
      </div>
    </div>
  );
}
