import { Table as ReactTable, flexRender } from "@tanstack/react-table";
import { Table as BootstrapTable } from "react-bootstrap";
import { PiCaretDownBold, PiCaretUpBold } from "react-icons/pi";
import { QueryParams } from "@/hooks/use-query-params";
import { Fragment, memo, ReactNode } from "react";

interface DataTableProps<T> {
    table: ReactTable<T>;
    params: QueryParams;
    onSort: (columnId: string) => void;
    defaultSortColumn?: string;
    renderSubComponent?: (props: { row: T }) => ReactNode;
    isExpanded?: (rowId: string) => boolean;
    rowClassName?: (row: T) => string;
}

function DataTable<T>({ table, params, onSort, defaultSortColumn = 'created_at', renderSubComponent, isExpanded, rowClassName }: DataTableProps<T>) {
    const getSortIcon = (columnId: string, canSort: boolean) => {
        if (!canSort) return null;

        if (params.sort === columnId) {
            return params.order === 'asc'
                ? <PiCaretUpBold className="text-primary" />
                : <PiCaretDownBold className="text-primary" />;
        }

        if (columnId === defaultSortColumn && !params.sort) {
            return <PiCaretDownBold className="text-primary opacity-50" />;
        }

        return null;
    };

    return (
        <BootstrapTable responsive hover className="table-theme align-middle">
            <thead>
                {table.getHeaderGroups().map(headerGroup => (
                    <tr key={headerGroup.id}>
                        {headerGroup.headers.map(header => (
                            <th key={header.id}>
                                {header.isPlaceholder ? null : (
                                    <div
                                        className={
                                            header.column.getCanSort()
                                                ? "cursor-pointer select-none d-flex align-items-center gap-2"
                                                : "d-flex align-items-center gap-2"
                                        }
                                        onClick={
                                            header.column.getCanSort()
                                                ? () => onSort(header.column.id)
                                                : undefined
                                        }
                                    >
                                        {flexRender(
                                            header.column.columnDef.header,
                                            header.getContext()
                                        )}
                                        {getSortIcon(header.column.id, header.column.getCanSort())}
                                    </div>
                                )}
                            </th>
                        ))}
                    </tr>
                ))}
            </thead>
            <tbody>
                {table.getRowModel().rows.map(row => (
                    <Fragment key={row.id}>
                        <tr className={rowClassName ? rowClassName(row.original) : ''}>
                            {row.getVisibleCells().map(cell => (
                                <td key={cell.id}>
                                    {flexRender(
                                        cell.column.columnDef.cell,
                                        cell.getContext()
                                    )}
                                </td>
                            ))}
                        </tr>
                        {((isExpanded && isExpanded(row.id)) || row.getIsExpanded()) && renderSubComponent && (
                            <tr>
                                <td colSpan={row.getVisibleCells().length} className="p-0">
                                    {renderSubComponent({ row: row.original })}
                                </td>
                            </tr>
                        )}
                    </Fragment>
                ))}
            </tbody>
        </BootstrapTable>
    );
}

// Memoize the component to prevent unnecessary re-renders
export default memo(DataTable) as typeof DataTable;