import { useCallback, useMemo, useState } from "react";
import type { SortingState } from "@tanstack/react-table";

export type SortDirection = "asc" | "desc";

export interface PaginationParams {
  page: number;
  limit: number;
  searchQuery: string;
  sortBy?: string;
  sortDirection?: SortDirection;
}

export interface PaginationController {
  params: PaginationParams;

  set: <K extends keyof PaginationParams>(
    key: K,
    value: PaginationParams[K],
  ) => void;

  patch: (payload: Partial<PaginationParams>) => void;

  reset: () => void;

  // Ready-to-spread config for <DataTable sorting={...} />
  sortingConfig: {
    state: SortingState;
    onChange: (next: SortingState) => void;
  };
}

interface UsePaginationOptions {
  initialState?: Partial<PaginationParams>;
}

const DEFAULT_STATE: PaginationParams = {
  page: 1,
  limit: 10,
  searchQuery: "",
  sortBy: undefined,
  sortDirection: undefined,
};

export function useAppPagination({
  initialState,
}: UsePaginationOptions = {}): PaginationController {
  const [params, setParams] = useState<PaginationParams>({
    ...DEFAULT_STATE,
    ...initialState,
  });

  const set = <K extends keyof PaginationParams>(
    key: K,
    value: PaginationParams[K],
  ) => {
    setParams((prev) => ({
      ...prev,
      [key]: value,
    }));
  };

  const patch = (payload: Partial<PaginationParams>) => {
    setParams((prev) => ({
      ...prev,
      ...payload,
    }));
  };

  const reset = () => {
    setParams({
      ...DEFAULT_STATE,
      ...initialState,
    });
  };

  // Derive TanStack's SortingState from our flat params
  const sortingState: SortingState = useMemo(() => {
    if (!params.sortBy) return [];
    return [{ id: params.sortBy, desc: params.sortDirection === "desc" }];
  }, [params.sortBy, params.sortDirection]);

  // Adapter: DataTable gives us SortingState, we convert + patch + reset page
  const handleSortingChange = useCallback((next: SortingState) => {
    const sort = next[0];

    setParams((prev) => ({
      ...prev,
      sortBy: sort?.id,
      sortDirection: sort ? (sort.desc ? "desc" : "asc") : undefined,
      page: 1, // reset to first page whenever sort changes
    }));
  }, []);

  const sortingConfig = useMemo(
    () => ({
      state: sortingState,
      onChange: handleSortingChange,
    }),
    [sortingState, handleSortingChange],
  );

  return {
    params,
    set,
    patch,
    reset,
    sortingConfig,
  };
}
