import type { Cell, Table } from '@tanstack/react-table'
import { ShortTextCell } from './cell-variants/short-text-cell'
import { LongTextCell } from './cell-variants/long-text-cell'
import { NumberCell } from './cell-variants/number-cell'
import { SelectCell } from './cell-variants/select-cell'
import { MultiSelectCell } from './cell-variants/multi-select-cell'
import { CheckboxCell } from './cell-variants/checkbox-cell'
import { DateCell } from './cell-variants/date-cell'
import { ReactNodeCell } from './cell-variants/react-node-cell'
import { GanttCell } from './cell-variants/gantt-cell'

type DataGridCellProps<TData> = {
  cell: Cell<TData, unknown>
  table: Table<TData>
}

export function DataGridCell<TData>({ cell, table }: DataGridCellProps<TData>) {
  const meta = table.options.meta
  const originalRowIndex = cell.row.index

  const rows = table.getRowModel().rows
  const displayRowIndex = rows.findIndex((row) => row.original === cell.row.original)
  const rowIndex = displayRowIndex >= 0 ? displayRowIndex : originalRowIndex
  const columnId = cell.column.id

  const isFocused = meta?.focusedCell?.rowIndex === rowIndex && meta?.focusedCell?.columnId === columnId
  const isEditing = meta?.editingCell?.rowIndex === rowIndex && meta?.editingCell?.columnId === columnId
  const isSelected = meta?.getIsCellSelected?.(rowIndex, columnId) ?? false

  const cellOpts = cell.column.columnDef.meta?.cell
  const variant = cellOpts?.variant ?? 'text'

  switch (variant) {
    case 'short-text':
      return (
        <ShortTextCell
          cell={cell as Cell<TData, string>}
          table={table}
          rowIndex={rowIndex}
          columnId={columnId}
          isEditing={isEditing}
          isFocused={isFocused}
          isSelected={isSelected}
        />
      )
    case 'long-text':
      return (
        <LongTextCell
          cell={cell as Cell<TData, string>}
          table={table}
          rowIndex={rowIndex}
          columnId={columnId}
          isEditing={isEditing}
          isFocused={isFocused}
          isSelected={isSelected}
        />
      )
    case 'number':
      return (
        <NumberCell
          cell={cell as Cell<TData, number>}
          table={table}
          rowIndex={rowIndex}
          columnId={columnId}
          isEditing={isEditing}
          isFocused={isFocused}
          isSelected={isSelected}
        />
      )
    case 'select':
      return (
        <SelectCell
          cell={cell as Cell<TData, string>}
          table={table}
          rowIndex={rowIndex}
          columnId={columnId}
          isEditing={isEditing}
          isFocused={isFocused}
          isSelected={isSelected}
        />
      )
    case 'multi-select':
      return (
        <MultiSelectCell
          cell={cell as Cell<TData, string[]>}
          table={table}
          rowIndex={rowIndex}
          columnId={columnId}
          isEditing={isEditing}
          isFocused={isFocused}
          isSelected={isSelected}
        />
      )
    case 'checkbox':
      return (
        <CheckboxCell
          cell={cell as Cell<TData, boolean>}
          table={table}
          rowIndex={rowIndex}
          columnId={columnId}
          isEditing={isEditing}
          isFocused={isFocused}
          isSelected={isSelected}
        />
      )
    case 'date':
      return (
        <DateCell
          cell={cell as Cell<TData, string>}
          table={table}
          rowIndex={rowIndex}
          columnId={columnId}
          isEditing={isEditing}
          isFocused={isFocused}
          isSelected={isSelected}
        />
      )
    case 'react-node':
      return (
        <ReactNodeCell
          cell={cell as Cell<TData, React.ReactNode>}
          table={table}
          rowIndex={rowIndex}
          columnId={columnId}
          isEditing={isEditing}
          isFocused={isFocused}
          isSelected={isSelected}
        />
      )
    case 'gantt':
      return (
        <GanttCell
          cell={cell as Cell<TData, { start: Date; end: Date } | null>}
          table={table}
          rowIndex={rowIndex}
          columnId={columnId}
          isEditing={isEditing}
          isFocused={isFocused}
          isSelected={isSelected}
        />
      )

    default:
      return (
        <ShortTextCell
          cell={cell as Cell<TData, string>}
          table={table}
          rowIndex={rowIndex}
          columnId={columnId}
          isEditing={isEditing}
          isFocused={isFocused}
          isSelected={isSelected}
        />
      )
  }
}
