import { MantineReactTable, MRT_Cell, MRT_Column, MRT_Row, MRT_RowData, MRT_TableInstance, MRT_TableOptions, useMantineReactTable, Xor } from "mantine-react-table";
import { useNejReactTable } from "./useNejReactTable";
import { LoadingOverlay } from "@mantine/core";
import { ReactNode, RefObject } from "react";

export type TableInstance<TData extends MRT_RowData> = MRT_TableInstance<TData> & { loading: boolean }
type TableInstanceProp<TData extends MRT_RowData> = {
    table: TableInstance<TData>;
};

export type NejReactTableOptions<TData extends MRT_RowData> = Omit<MRT_TableOptions<TData>, "data"> & { data?: TData[] };

export type NejReactRenderActions<TData extends MRT_RowData> =  (props: {
    cell: MRT_Cell<TData, unknown>;
    column: MRT_Column<TData, unknown>;
    renderedCellValue: ReactNode | number | string;
    renderedColumnIndex?: number;
    renderedRowIndex?: number;
    row: MRT_Row<TData>;
    rowRef?: RefObject<HTMLTableRowElement>;
    table: MRT_TableInstance<TData>;
}) => ReactNode;

export type CommonlyExposedNejReactTableProps<TData extends MRT_RowData> = CommonlyForwardedNejReactTableOptions<TData> & { renderActions?: NejReactRenderActions<TData> }

export type CommonlyForwardedNejReactTableOptions<TData extends MRT_RowData> = Omit<NejReactTableOptions<TData>, "columns">

type Props<TData extends MRT_RowData> = Xor<
    TableInstanceProp<TData>,
    NejReactTableOptions<TData>
>;

const isTableInstanceProp = <TData extends MRT_RowData>(
    props: Props<TData>,
): props is TableInstanceProp<TData> =>
    (props as TableInstanceProp<TData>).table !== undefined;

export type RenderActionType<TData extends MRT_RowData, TValue = unknown> = (data: {
    cell: MRT_Cell<TData, TValue>;
    column: MRT_Column<TData, TValue>;
    renderedCellValue: ReactNode | number | string;
    renderedColumnIndex?: number;
    renderedRowIndex?: number;
    row: MRT_Row<TData>;
    rowRef?: RefObject<HTMLTableRowElement>;
    table: MRT_TableInstance<TData>;
}) => React.ReactNode

export const NejReactTable = <TData extends MRT_RowData>(
    props: Props<TData>,
) => {
    let table: TableInstance<TData>;

    if (isTableInstanceProp(props)) {
        table = props.table;
    } else {
        table = useNejReactTable(props);
    }

    return <div tw="relative">
        <LoadingOverlay visible={table.loading} />
        <MantineReactTable table={table} />
    </div>;
};
