import React, { type ReactNode, type ReactElement } from 'react'
import { type IDefaultTableRow, type ITableColumn, type ITableProps } from '@/Types/TableTypes'
import { makeClassName } from '@/utils'

const defaultOptions = {
  defaultClassName: 'table-auto w-full',
  defaultHeaderClassName: 'border-b border-slate-400 p-4 text-slate-800',
  defaultCellClassName: 'border-b border-slate-100 dark:border-slate-700 p-4 text-slate-500 dark:text-slate-400',
  scrollable: true

}

const defaultScrollableHeaderClass = 'bg-white border-b sticky top-0 z-10'

const Table = <T extends IDefaultTableRow, >({
  columns,
  data,
  className = '',
  tbodyClassName = '',
  theadClassName = '',
  rowClassName,
  options,
  defaultFullSpanClassName = ''
}: ITableProps<T>): ReactElement => {
  const ops = {
    ...options,
    ...defaultOptions
  }
  function cellAccessor<T> (column: ITableColumn<T>, row: T): string | ReactNode {
    let val
    if (column.accessor !== undefined) {
      val = column.accessor(row)
    } else if (typeof row === 'object' && row !== null && column.id in row) {
      val = String((row as Record<string, unknown>)[column.id])
    }
    if (val === undefined) {
      return ''
    }
    return val
  }
  return (
        <table className={makeClassName({ defaultClassName: ops.defaultClassName, className })}>
            <thead className={makeClassName({ defaultClassName: ops.scrollable ?? true ? defaultScrollableHeaderClass : '', className: theadClassName })}><tr>{columns.map(column =>
                <th key={column.id} className={makeClassName({ defaultClassName: ops.defaultHeaderClassName, className: column.headerClassName })}>
                    {column.label}
                </th>
            )}</tr></thead>
            <tbody className={makeClassName({ className: tbodyClassName })}>{data.map((row, i) =>
                <tr key={String(i)} className={rowClassName ?? ''}>
                  {
                    row.fullSpanContent !== undefined
                      ? <td colSpan={columns.length} className={makeClassName({
                        defaultClassName: defaultFullSpanClassName,
                        className: row.fullSpanClassName
                      })}>{row.fullSpanContent}</td>
                      : columns.map(column => (
                          <td key={`${column.id}.${String(i)}`} className={makeClassName({ defaultClassName: ops.defaultCellClassName, className: column.cellClassName })}>
                              {cellAccessor(column, row)}
                          </td>
                      ))
                  }
                </tr>
            )}</tbody>
        </table>
  )
}

export default Table
