import type { ReactNode } from 'react'
import { ArrowUpDown, ArrowUp, ArrowDown } from 'lucide-react'
import { cn } from '@/lib/utils'

export type SortOrder = 'asc' | 'desc'

export interface Column<T> {
  header: string
  cell: (row: T) => ReactNode
  className?: string
  width?: string
  /** Если задан — заголовок становится кликабельным, при клике вызывает onSortChange. */
  sortKey?: string
}

interface DataTableProps<T> {
  rows: T[]
  columns: Column<T>[]
  rowKey: (row: T) => string
  onRowClick?: (row: T) => void
  onRowDoubleClick?: (row: T) => void
  empty?: ReactNode
  isLoading?: boolean
  /** If true (default), the table wraps itself in a scrollable container with a sticky thead.
   * If false, use when the caller provides its own scroll container. */
  scrollable?: boolean
  /** Текущий ключ сортировки (null если сортировка не активна). */
  sortKey?: string | null
  sortOrder?: SortOrder
  /** Колбэк кликов по заголовку. Если не задан — заголовки не кликабельны. */
  onSortChange?: (key: string, order: SortOrder) => void
}

export function DataTable<T>({
  rows, columns, rowKey, onRowClick, onRowDoubleClick, empty, isLoading, scrollable = true,
  sortKey, sortOrder, onSortChange,
}: DataTableProps<T>) {
  const handleHeaderClick = (key: string) => {
    if (!onSortChange) return
    const nextOrder: SortOrder = sortKey === key && sortOrder === 'asc' ? 'desc' : 'asc'
    onSortChange(key, nextOrder)
  }

  const renderHeader = (c: Column<T>) => {
    if (!c.sortKey || !onSortChange) return c.header
    const active = sortKey === c.sortKey
    const Icon = active ? (sortOrder === 'desc' ? ArrowDown : ArrowUp) : ArrowUpDown
    return (
      <button
        type="button"
        onClick={() => handleHeaderClick(c.sortKey!)}
        className={cn(
          'inline-flex items-center gap-1 select-none',
          active ? 'text-slate-900 dark:text-slate-100' : 'hover:text-slate-700 dark:hover:text-slate-300',
        )}
      >
        <span>{c.header}</span>
        <Icon className={cn('w-3 h-3', active ? 'opacity-100' : 'opacity-40')} />
      </button>
    )
  }

  const table = (
    <table className="w-full min-w-[640px] text-sm border-separate border-spacing-0">
      <thead className="sticky top-0 z-10 bg-slate-50 dark:bg-slate-800/90 backdrop-blur text-left">
        <tr>
          {columns.map((c, i) => (
            <th
              key={i}
              className={cn(
                'px-3 sm:px-4 py-2.5 font-medium text-xs uppercase tracking-wide text-slate-500 border-b border-slate-200 dark:border-slate-700 whitespace-nowrap',
                c.className,
              )}
              style={c.width ? { width: c.width } : undefined}
            >
              {renderHeader(c)}
            </th>
          ))}
        </tr>
      </thead>
      <tbody>
        {isLoading ? (
          <tr>
            <td colSpan={columns.length} className="px-4 py-8 text-center text-slate-400">
              Загрузка…
            </td>
          </tr>
        ) : rows.length === 0 ? (
          <tr>
            <td colSpan={columns.length} className="px-4 py-8 text-center text-slate-400">
              {empty ?? 'Нет данных'}
            </td>
          </tr>
        ) : (
          rows.map((row) => (
            <tr
              key={rowKey(row)}
              onClick={() => onRowClick?.(row)}
              onDoubleClick={() => onRowDoubleClick?.(row)}
              className={cn(
                (onRowClick || onRowDoubleClick) && 'hover:bg-slate-50 dark:hover:bg-slate-800/30',
                onRowDoubleClick && 'cursor-pointer select-none',
                onRowClick && !onRowDoubleClick && 'cursor-pointer',
              )}
            >
              {columns.map((c, i) => (
                <td
                  key={i}
                  className={cn(
                    'px-3 sm:px-4 py-2.5 text-slate-700 dark:text-slate-200 border-b border-slate-100 dark:border-slate-800',
                    c.className,
                  )}
                >
                  {c.cell(row)}
                </td>
              ))}
            </tr>
          ))
        )}
      </tbody>
    </table>
  )

  if (!scrollable) {
    return (
      <div className="bg-white dark:bg-slate-900 rounded-lg border border-slate-200 dark:border-slate-800 overflow-hidden">
        {table}
      </div>
    )
  }

  return (
    <div className="bg-white dark:bg-slate-900 rounded-lg border border-slate-200 dark:border-slate-800 h-full overflow-auto">
      {table}
    </div>
  )
}
