"use client";

import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { cn } from "@/lib/utils";
import { useTranslations } from "next-intl";
import type { CSSProperties, ReactNode } from "react";

export interface Column<T> {
  key: string;
  header: ReactNode;
  render: (item: T, rowNumber: number) => ReactNode;
  width?: number | string;
  align?: "start" | "center" | "end";
  headerClassName?: string;
  cellClassName?: string;
}

interface DataTableProps<T> {
  data: T[];
  columns: Column<T>[];
  page?: number;
  perPage?: number;
  getRowId?: (item: T) => string | number;
  showRowNumber?: boolean;
  rowNumberHeader?: ReactNode;
  minWidth?: number | string;
  emptyMessage?: ReactNode;
  rowClassName?: string | ((item: T, index: number) => string);
  onRowClick?: (item: T) => void;
  className?: string;
}

const alignClass = (align: Column<unknown>["align"] = "center"): string =>
  align === "start"
    ? "text-start"
    : align === "end"
      ? "text-end"
      : "text-center";

const sizeToCss = (value: number | string): string =>
  typeof value === "number" ? `${value}px` : value;

export function DataTable<T extends { id?: string | number }>({
  data,
  columns,
  page = 1,
  perPage,
  getRowId,
  showRowNumber = true,
  rowNumberHeader = "#",
  minWidth,
  emptyMessage,
  rowClassName,
  onRowClick,
  className,
}: DataTableProps<T>) {
  const tCommon = useTranslations("common");
  const resolvedEmpty = emptyMessage ?? tCommon("noResults");
  const effectivePerPage = perPage ?? data.length;

  if (!data.length) {
    return (
      <div className="flex h-52 items-center justify-center text-sm text-muted-foreground">
        {resolvedEmpty}
      </div>
    );
  }

  const tableStyle: CSSProperties | undefined =
    minWidth === undefined ? undefined : { minWidth: sizeToCss(minWidth) };

  return (
    <div className={cn("w-full overflow-x-auto", className)}>
      <Table className="border-collapse bg-card" style={tableStyle}>
        <TableHeader>
          <TableRow className="border-b border-border bg-highlights-bg hover:bg-highlights-bg">
            {showRowNumber && (
              <TableHead className="h-12 w-14 px-4 text-center text-sm font-bold text-foreground">
                {rowNumberHeader}
              </TableHead>
            )}
            {columns.map((column) => {
              const colStyle: CSSProperties | undefined =
                column.width === undefined
                  ? undefined
                  : { width: sizeToCss(column.width) };
              return (
                <TableHead
                  key={column.key}
                  style={colStyle}
                  className={cn(
                    "h-12 px-4 text-sm font-bold text-foreground",
                    alignClass(column.align),
                    column.headerClassName
                  )}
                >
                  {column.header}
                </TableHead>
              );
            })}
          </TableRow>
        </TableHeader>

        <TableBody>
          {data.map((item, index) => {
            const rowNumber = (page - 1) * effectivePerPage + index + 1;
            const id = getRowId ? getRowId(item) : (item.id ?? index);
            const resolvedRowClass =
              typeof rowClassName === "function"
                ? rowClassName(item, index)
                : rowClassName;

            return (
              <TableRow
                key={id}
                onClick={onRowClick ? () => onRowClick(item) : undefined}
                className={cn(
                  "h-[72px] border-b border-border bg-card hover:bg-card",
                  onRowClick && "cursor-pointer",
                  resolvedRowClass
                )}
              >
                {showRowNumber && (
                  <TableCell className="px-4 text-center text-sm">
                    {rowNumber}
                  </TableCell>
                )}
                {columns.map((column) => {
                  const colStyle: CSSProperties | undefined =
                    column.width === undefined
                      ? undefined
                      : { width: sizeToCss(column.width) };
                  return (
                    <TableCell
                      key={column.key}
                      style={colStyle}
                      className={cn(
                        "px-4 text-sm text-foreground",
                        alignClass(column.align),
                        column.cellClassName
                      )}
                    >
                      {column.render(item, rowNumber)}
                    </TableCell>
                  );
                })}
              </TableRow>
            );
          })}
        </TableBody>
      </Table>
    </div>
  );
}
