import * as React from "react"

import { Badge } from "@/components/ui/badge"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { cn } from "@/lib/utils"

export type DataGridColumn<TData> = {
  key: keyof TData | string
  header: React.ReactNode
  render?: (row: TData) => React.ReactNode
  className?: string
}

export type DataGridProps<TData extends Record<string, unknown>> = React.ComponentProps<"div"> & {
  columns: DataGridColumn<TData>[]
  rows: TData[]
  rowKey?: keyof TData | ((row: TData, index: number) => React.Key)
  emptyLabel?: React.ReactNode
  title?: React.ReactNode
  description?: React.ReactNode
}

function DataGrid<TData extends Record<string, unknown>>({
  columns,
  rows,
  rowKey,
  emptyLabel = "No rows found.",
  title,
  description,
  className,
  ...props
}: DataGridProps<TData>) {
  return (
    <div data-slot="data-grid" className={cn("space-y-3", className)} {...props}>
      {(title || description) && (
        <div className="flex flex-wrap items-start justify-between gap-3">
          <div>
            {title && <h3 className="text-base font-semibold text-foreground">{title}</h3>}
            {description && <p className="mt-1 text-sm text-muted-foreground">{description}</p>}
          </div>
          <Badge variant="secondary">{rows.length} rows</Badge>
        </div>
      )}
      <Table>
        <TableHeader>
          <TableRow>
            {columns.map((column) => (
              <TableHead key={String(column.key)} className={column.className}>
                {column.header}
              </TableHead>
            ))}
          </TableRow>
        </TableHeader>
        <TableBody>
          {rows.length > 0 ? (
            rows.map((row, rowIndex) => (
              <TableRow key={resolveRowKey(row, rowIndex, rowKey)}>
                {columns.map((column) => (
                  <TableCell key={String(column.key)} className={column.className}>
                    {column.render ? column.render(row) : renderCell(row[column.key])}
                  </TableCell>
                ))}
              </TableRow>
            ))
          ) : (
            <TableRow>
              <TableCell colSpan={columns.length} className="h-24 text-center text-muted-foreground">
                {emptyLabel}
              </TableCell>
            </TableRow>
          )}
        </TableBody>
      </Table>
    </div>
  )
}

function resolveRowKey<TData extends Record<string, unknown>>(
  row: TData,
  index: number,
  rowKey?: keyof TData | ((row: TData, index: number) => React.Key)
) {
  if (typeof rowKey === "function") return rowKey(row, index)
  if (rowKey && row[rowKey] != null) return String(row[rowKey])
  return index
}

function renderCell(value: unknown) {
  if (React.isValidElement(value)) return value
  if (value == null) return null
  if (typeof value === "boolean") return value ? "Yes" : "No"
  return String(value)
}

export { DataGrid }
