'use client';

import { GripVertical, PlusCircle, Trash2 } from 'lucide-react';

import { Button } from '@/components/ui/button';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { cn } from '@/lib/utils';

export type LineItemsColumn<TItem> = {
  key: string;
  label: string;
  className?: string;
  headerClassName?: string;
  width?: string | number;
  renderCell: (args: { item: TItem; index: number }) => React.ReactNode;
};

export type LineItemsTableProps<TItem> = {
  items: TItem[];
  columns: Array<LineItemsColumn<TItem>>;
  emptyLabel?: string;
  addLabel?: string;
  allowAdd?: boolean;
  allowDelete?: boolean;
  showLineNumber?: boolean;
  showReorderHandle?: boolean;
  containerClassName?: string;
  tableClassName?: string;
  onAddRow?: () => void;
  onDeleteRow?: (index: number) => void;
};

export function LineItemsTable<TItem>({
  items,
  columns,
  emptyLabel,
  addLabel,
  allowAdd = false,
  allowDelete = true,
  showLineNumber = true,
  showReorderHandle = false,
  containerClassName,
  tableClassName,
  onAddRow,
  onDeleteRow,
}: LineItemsTableProps<TItem>) {
  const hasItems = items.length > 0;
  const colSpan = columns.length + (showLineNumber ? 1 : 0) + (showReorderHandle ? 1 : 0) + (allowDelete ? 1 : 0);

  return (
    <div className={cn('rounded-md border overflow-hidden', containerClassName)}>
      <Table className={tableClassName}>
        <TableHeader>
          <TableRow>
            {showLineNumber ? <TableHead className="w-[56px] text-center">#</TableHead> : null}
            {showReorderHandle ? <TableHead className="w-[44px]" /> : null}
            {columns.map((column) => (
              <TableHead
                key={column.key}
                className={column.headerClassName}
                style={column.width ? { width: column.width } : undefined}
              >
                {column.label}
              </TableHead>
            ))}
            {allowDelete ? <TableHead className="w-[56px] text-center" /> : null}
          </TableRow>
        </TableHeader>
        <TableBody>
          {hasItems ? (
            items.map((item, index) => (
              <TableRow key={index}>
                {showLineNumber ? (
                  <TableCell className="text-center text-xs text-muted-foreground">{index + 1}</TableCell>
                ) : null}
                {showReorderHandle ? (
                  <TableCell>
                    <GripVertical className="h-4 w-4 text-muted-foreground" />
                  </TableCell>
                ) : null}
                {columns.map((column) => (
                  <TableCell key={`${column.key}-${index}`} className={column.className}>
                    {column.renderCell({ item, index })}
                  </TableCell>
                ))}
                {allowDelete ? (
                  <TableCell className="text-center">
                    <Button
                      type="button"
                      variant="ghost"
                      size="icon"
                      className="h-8 w-8"
                      onClick={() => onDeleteRow?.(index)}
                    >
                      <Trash2 className="h-4 w-4" />
                    </Button>
                  </TableCell>
                ) : null}
              </TableRow>
            ))
          ) : (
            <TableRow>
              <TableCell colSpan={colSpan} className="h-20 text-center text-sm text-muted-foreground">
                {emptyLabel ?? 'No line items'}
              </TableCell>
            </TableRow>
          )}
        </TableBody>
      </Table>

      {allowAdd && onAddRow ? (
        <div className="border-t p-2 flex justify-end bg-muted/40">
          <Button type="button" variant="outline" size="sm" onClick={onAddRow}>
            <PlusCircle className="h-4 w-4 me-1" />
            {addLabel ?? 'Add line'}
          </Button>
        </div>
      ) : null}
    </div>
  );
}
