import { useListSearch } from "@/hooks/useListSearch"
import { ColumnDef, flexRender, getCoreRowModel, getPaginationRowModel, getSortedRowModel, PaginationState, useReactTable } from "@tanstack/react-table"
import clsx from "clsx"
import { useState } from "react"
import { BsArrowDown, BsArrowUp } from "react-icons/bs"
import Button from "../Low/Button"

interface Props<T> {
	data: T[]
	columns: ColumnDef<any, any>[]
	searchFields: string[][]
	size?: number
	onDownload?: (rows: T[]) => void
	isDownloadLoading?: boolean
	searchPlaceholder?: string
}

export default function Table<T>({ data, columns, searchFields, size = 16, onDownload, isDownloadLoading, searchPlaceholder }: Props<T>) {
	const [pagination, setPagination] = useState<PaginationState>({
		pageIndex: 0,
		pageSize: size,
	})

	const { rows, renderSearch } = useListSearch<T>(searchFields, data, searchPlaceholder);

	const table = useReactTable({
		data: rows,
		columns,
		getCoreRowModel: getCoreRowModel(),
		getSortedRowModel: getSortedRowModel(),
		getPaginationRowModel: getPaginationRowModel(),
		onPaginationChange: setPagination,
		state: {
			pagination
		}
	});

	return (
		<div className="w-full flex flex-col gap-2">
			<div className="w-full flex gap-2 items-end">
				{renderSearch()}
				{onDownload && (
					<Button isLoading={isDownloadLoading} className="w-full max-w-[200px] mb-1" variant="outline" onClick={() => onDownload(rows)}>
						Download
					</Button>
				)
				}
			</div>

			<div className="w-full flex gap-2 justify-between items-center">
				<div className="flex items-center gap-4 w-fit">
					<Button className="w-[200px] h-fit" disabled={!table.getCanPreviousPage()} onClick={() => table.previousPage()}>
						Previous Page
					</Button>
				</div>
				<div className="flex items-center gap-4 w-fit">
					<span className="flex items-center gap-1">
						<div>Page</div>
						<strong>
							{table.getState().pagination.pageIndex + 1} of{' '}
							{table.getPageCount().toLocaleString()}
						</strong>
						<div>| Total: {table.getRowCount().toLocaleString()}</div>
					</span>
					<Button className="w-[200px]" disabled={!table.getCanNextPage()} onClick={() => table.nextPage()}>
						Next Page
					</Button>
				</div>
			</div>

			<table className="rounded-xl bg-mti-purple-ultralight/40 w-full">
				<thead>
					{table.getHeaderGroups().map((headerGroup) => (
						<tr key={headerGroup.id}>
							{headerGroup.headers.map((header) => (
								<th className="py-4 px-4 text-left" key={header.id} colSpan={header.colSpan}>
									<div
										className={clsx(header.column.getCanSort() && 'cursor-pointer select-none', 'flex items-center gap-2')}
										onClick={header.column.getToggleSortingHandler()}
									>
										{flexRender(
											header.column.columnDef.header,
											header.getContext()
										)}
										{{
											asc: <BsArrowUp />,
											desc: <BsArrowDown />,
										}[header.column.getIsSorted() as string] ?? null}
									</div>
								</th>
							))}
						</tr>
					))}
				</thead>
				<tbody className="px-2 w-full">
					{table.getRowModel().rows.map((row) => (
						<tr className="odd:bg-white even:bg-mti-purple-ultralight/40 rounded-lg py-2" key={row.id}>
							{row.getVisibleCells().map((cell) => (
								<td className="px-4 py-2 items-center w-fit" key={cell.id}>
									{flexRender(cell.column.columnDef.cell, cell.getContext())}
								</td>
							))}
						</tr>
					))}
				</tbody>
			</table>
		</div>
	)
}
