import {
  useInfiniteQuery,
  type UseInfiniteQueryResult,
  type UseInfiniteQueryOptions,
  type InfiniteData,
  keepPreviousData,
} from "@tanstack/react-query";
import instance from "@/instance/instance";
import { ApiResponse } from "@/instance/instance.type";
import { buildQueryString } from "@/lib/common-function";

// Define meta type
interface PaginationMeta {
  page: number;
  lastPage: number;
  total?: number;
  hasMore?: boolean;
}

// Generic response type for paginated endpoints
export interface PaginatedResponse<TData> {
  data: TData[];
  meta: PaginationMeta;
}

interface UseInfiniteFetchDataProps<T> {
  url: string;
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  params?: Record<string, any>;
  enabled?: boolean;
  staleTime?: number;
  limit?: number;
  queryOptions?: Omit<
    UseInfiniteQueryOptions<
      PaginatedResponse<T>,
      Error,
      InfiniteData<PaginatedResponse<T>, number>,
      readonly unknown[],
      number
    >,
    "queryKey" | "queryFn" | "initialPageParam" | "getNextPageParam"
  >;
}

export function useInfiniteFetchData<T>({
  url,
  params = {},
  queryOptions = {},
  enabled = true,
  staleTime = 0,
  limit = 10,
}: UseInfiniteFetchDataProps<T>): UseInfiniteQueryResult<
  InfiniteData<PaginatedResponse<T>, number>,
  Error
> {
  return useInfiniteQuery({
    queryKey: [url, params, limit],

    queryFn: async ({ pageParam = 1 }) => {
      const allParams = { ...params, page: pageParam, limit };
      const queryString = buildQueryString(allParams);
      const headers: Record<string, string> = {};

      const response = await instance.get<ApiResponse<PaginatedResponse<T>>>(
        `${url}${queryString}`,
        { headers }
      );

      if (
        response?.data?.statusCode === 200 ||
        response?.data?.statusCode === 202
      ) {
        return response.data.data;
      }
      throw new Error(response?.data?.message ?? "Failed to fetch data");
    },

    initialPageParam: 1,

    getNextPageParam: (lastPage) => {
      console.log("lastPage", lastPage);

      if (
        (lastPage?.meta?.lastPage &&
          lastPage?.meta?.page &&
          lastPage?.meta?.lastPage !== 0 &&
          lastPage?.meta?.lastPage !== lastPage?.meta?.page) ||
        lastPage?.meta?.hasMore === true
      ) {
        return lastPage.meta.page + 1;
      }
      return undefined;
    },

    retry: 1,
    refetchOnWindowFocus: false,
    enabled,
    staleTime,
    placeholderData: keepPreviousData,
    ...queryOptions,
  });
}
