import { DataTableColumnProps, getDataTableSelectionColumn } from "@/components";
import { IListResponse_DTO } from "@shared/contexts";
import {
  OnChangeFn,
  PaginationState,
  SortingState,
  getCoreRowModel,
  useReactTable,
} from "@tanstack/react-table";
import { useCallback, useMemo, useState } from "react";
import { UseListQueryResult } from "../useDataSource";
import { usePaginationSyncWithLocation } from "../usePagination";

type TUseDataTableQueryResult<TData, TError> = UseListQueryResult<IListResponse_DTO<TData>, TError>;

type TUseDataTableQuery<TData, TError> = (params: {
  pagination: {
    pageIndex: number;
    pageSize: number;
  };
  enabled?: boolean;
}) => TUseDataTableQueryResult<TData, TError>;

type UseDataTableProps<TData, TValue, TError> = {
  fetchQuery: TUseDataTableQuery<TData, TError>;
  enabled?: boolean;

  columnOptions: DataTableColumnsOptionsProps<TData, TValue>;
  enableSorting?: boolean;
  enableHiding?: boolean;

  //initialPage?: number;
  //initialPageSize?: number;
};

type DataTableColumnsOptionsProps<TData, TValue> = {
  enableSelectionColumn?: boolean;
  columns: DataTableColumnsProps<TData, TValue>;
};

type DataTableColumnsProps<TData, TValue> = DataTableColumnProps<TData, TValue>[];

export const useQueryDataTable = <TData = unknown, TValue = unknown, TError = Error>({
  fetchQuery,
  enabled = true,

  columnOptions,
  enableSorting = false,
  enableHiding = false,
}: UseDataTableProps<TData, TValue, TError>) => {
  const defaultData = useMemo(() => [], []);

  const [rowSelection, setRowSelection] = useState({});
  const [pagination, setPagination] = usePaginationSyncWithLocation();
  const [sorting, setSorting] = useState<SortingState>([]);

  const paginationUpdater: OnChangeFn<PaginationState> = (updater) => {
    if (typeof updater === "function") {
      setPagination(updater(pagination));
    }
  };

  const sortingUpdater: OnChangeFn<SortingState> = (updater) => {
    if (typeof updater === "function") {
      setSorting(updater(sorting));
    }
  };

  const getTableColumns = useCallback(() => {
    const _columns = columnOptions.columns;
    if (columnOptions.enableSelectionColumn) {
      _columns.unshift(getDataTableSelectionColumn());
    }
    return _columns;
  }, [columnOptions]);

  const queryResult: TUseDataTableQueryResult<TData, TError> = fetchQuery({
    pagination,
    enabled,
  });

  const table = useReactTable<TData>({
    columns: getTableColumns(),
    data: queryResult.data?.items ?? defaultData,
    getCoreRowModel: getCoreRowModel(),
    //getPaginationRowModel: getPaginationRowModel(),

    enableRowSelection: columnOptions.enableSelectionColumn,
    onRowSelectionChange: setRowSelection,

    enableSorting,
    onSortingChange: sortingUpdater,

    enableHiding,
    //onColumnVisibilityChange: columnVisibilityUpdater,

    state: {
      pagination,
      sorting,
      rowSelection,
    },
    manualPagination: true,
    //autoResetPageIndex: true,
    pageCount: queryResult?.data?.total_pages ?? -1,
    onPaginationChange: paginationUpdater,

    debugTable: true,
  });

  return {
    table,
    queryResult,
  };
};
