'use client'

import { ReactNode } from 'react'
import Skeleton from '@mui/material/Skeleton'
import Typography from '@mui/material/Typography'
import type { Cell, Row, Table as ReactTableType } from '@tanstack/react-table'
import { flexRender } from '@tanstack/react-table'

import tableStyles from '@core/styles/table.module.css'

type DataTableProps<TData> = {
  table: ReactTableType<TData>
  isLoading?: boolean
  skeletonRows?: number
  noDataLabel: string
  rowClassName?: string | ((row: Row<TData>) => string)
  cellClassName?: string | ((cell: Cell<TData, unknown>) => string)
  loadingRender?: ReactNode
}

const resolveClassName = <T,>(
  value?: string | ((arg: T) => string),
  arg?: T
): string | undefined => {
  if (!value) return undefined
  return typeof value === 'function' ? value(arg as T) : value
}

const DataTable = <TData,>({
  table,
  isLoading,
  skeletonRows = 6,
  noDataLabel,
  rowClassName,
  cellClassName,
  loadingRender
}: DataTableProps<TData>) => {
  const rows = table.getRowModel().rows
  const columns = table.getVisibleFlatColumns()

  return (
    <div className='overflow-x-auto'>
      <table className={tableStyles.table}>
        <thead>
          {table.getHeaderGroups().map(headerGroup => (
            <tr key={headerGroup.id}>
              {headerGroup.headers.map(header => (
                <th key={header.id}>{flexRender(header.column.columnDef.header, header.getContext())}</th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody>
          {isLoading ? (
            loadingRender || (
              Array.from({ length: skeletonRows }).map((_, index) => (
                <tr key={`skeleton-${index}`}>
                  {columns.map(column => (
                    <td key={`${column.id}-${index}`}>
                      <Skeleton variant='rounded' height={24} />
                    </td>
                  ))}
                </tr>
              ))
            )
          ) : rows.length === 0 ? (
            <tr>
              <td colSpan={columns.length}>
                <Typography align='center' variant='body2' className='py-6'>
                  {noDataLabel}
                </Typography>
              </td>
            </tr>
          ) : (
            rows.map(row => (
              <tr key={row.id} className={resolveClassName(rowClassName, row)}>
                {row.getVisibleCells().map(cell => (
                  <td key={cell.id} className={resolveClassName(cellClassName, cell)}>
                    {flexRender(cell.column.columnDef.cell, cell.getContext())}
                  </td>
                ))}
              </tr>
            ))
          )}
        </tbody>
      </table>
    </div>
  )
}

export default DataTable

