import Paper from "@mui/material/Paper";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import { t } from "i18next";
import { forwardRef, ReactNode } from "react";
import { TableVirtuoso, TableComponents } from "react-virtuoso";

function createVirtuosoTableComponents<T>(): TableComponents<T> {
	return {
		Scroller: forwardRef<HTMLDivElement>((props, ref) => (
			<TableContainer component={Paper} {...props} ref={ref} />
		)),
		Table: (props) => (
			<Table
				{...props}
				sx={{ borderCollapse: "separate", tableLayout: "fixed" }}
			/>
		),
		TableHead: forwardRef<HTMLTableSectionElement>((props, ref) => (
			<TableHead {...props} ref={ref} />
		)),
		TableRow,
		TableBody: forwardRef<HTMLTableSectionElement>((props, ref) => (
			<TableBody {...props} ref={ref} />
		)),
	};
}

function fixedHeaderContent<T>(columns: ColumnProps<T>[]) {
	return (
		<TableRow>
			{columns.map((column) => (
				<TableCell
					key={column.fieldName.toString()}
					variant="head"
					// align={column.numeric || false ? "right" : "left"}
					// style={{ width: column.width }}
					sx={{
						backgroundColor: "background.paper",
						textWrap: "nowrap",
						fontWeight: "bold",
					}}
				>
					{t(column.titleKey)}
				</TableCell>
			))}
		</TableRow>
	);
}

function getValue<T>(column: ColumnProps<T>, row: T) {
	return row[column.fieldName];
}

function rowContent<T>(columns: ColumnProps<T>[], row: T, index: number) {
	return (
		<>
			{columns.map((column, columnIndex) => (
				<TableCell
					key={columnIndex}
					sx={{
						backgroundColor: index % 2 === 0 ? "#f5f5f5" : "background.paper",
						textWrap: "nowrap",
					}}
				>
					{column.render ? (
						column.render(row)
					) : (
						<>{getValue(column, row)}</>
					)}
				</TableCell>
			))}
		</>
	);
}

export interface ColumnProps<T> {
	fieldName: keyof T;
	titleKey: string;
	render?: (row: T) => ReactNode;
}

export interface Props<T> {
	columns: ColumnProps<T>[];
	data: T[];
	height: number;
}

export function ReactVirtualizedTable<T>({ columns, data, height }: Props<T>) {
	return (
		<Paper style={{ height: height, width: "100%" }}>
			<TableVirtuoso
				data={data}
				components={createVirtuosoTableComponents<T>()}
				fixedHeaderContent={() => fixedHeaderContent(columns)}
				itemContent={(index, row) => rowContent(columns, row, index)}
			/>
		</Paper>
	);
}
