import { infiniteQueryOptions, queryOptions } from '@tanstack/react-query'
import {
  getAccountById,
  getAccountByUsername,
  getAccountFollowers,
  getAccountFollowing,
  getAccountRelationship,
  getFollowRequests,
  getMutualFollowing,
  getSelfAccount,
} from 'src/lib/api'
import type { Account, Relationship } from 'src/lib/api-types'
import type { LinkPaginatedResponse } from 'src/lib/pagination'
import { queryKeys } from './keys'

export const accountQueries = {
  byId: (id: string) =>
    queryOptions({
      queryKey: queryKeys.accounts.byId(id),
      queryFn: () => getAccountById(id),
      staleTime: 5 * 60 * 1000,
      gcTime: 60 * 60 * 1000,
    }),

  byUsername: (username: string) =>
    queryOptions<Account>({
      queryKey: queryKeys.accounts.byUsername(username),
      queryFn: () => getAccountByUsername(username),
      staleTime: 5 * 60 * 1000,
      gcTime: 60 * 60 * 1000,
    }),

  relationship: (userId: string) =>
    queryOptions<Relationship>({
      queryKey: queryKeys.accounts.relationship(userId),
      queryFn: () => getAccountRelationship(userId),
      staleTime: 30 * 1000,
      gcTime: 10 * 60 * 1000,
    }),

  followers: (id: string) =>
    infiniteQueryOptions({
      queryKey: queryKeys.accounts.followers(id),
      queryFn: ({ pageParam }) => getAccountFollowers(id, pageParam as string),
      initialPageParam: null as string | null,
      staleTime: 5 * 60 * 1000,
      gcTime: 60 * 60 * 1000,
      getNextPageParam: (lastPage: LinkPaginatedResponse<unknown>) =>
        lastPage.nextPage ?? undefined,
      getPreviousPageParam: (lastPage: LinkPaginatedResponse<unknown>) =>
        lastPage.prevPage ?? undefined,
    }),

  following: (id: string) =>
    infiniteQueryOptions({
      queryKey: queryKeys.accounts.following(id),
      queryFn: ({ pageParam }) => getAccountFollowing(id, pageParam as string),
      initialPageParam: null as string | null,
      staleTime: 5 * 60 * 1000,
      gcTime: 60 * 60 * 1000,
      getNextPageParam: (lastPage: LinkPaginatedResponse<unknown>) =>
        lastPage.nextPage ?? undefined,
      getPreviousPageParam: (lastPage: LinkPaginatedResponse<unknown>) =>
        lastPage.prevPage ?? undefined,
    }),

  self: () =>
    queryOptions({
      queryKey: queryKeys.accounts.self(),
      queryFn: getSelfAccount,
      staleTime: 5 * 60 * 1000,
      gcTime: 60 * 60 * 1000,
    }),

  mutualFollowing: (userId: string) =>
    queryOptions({
      queryKey: queryKeys.accounts.mutuals(userId),
      queryFn: () => getMutualFollowing(userId),
      staleTime: 5 * 60 * 1000,
      gcTime: 60 * 60 * 1000,
    }),

  selfProfile: (id: string) =>
    queryOptions<Account>({
      queryKey: queryKeys.accounts.selfProfile(id),
      queryFn: () => getAccountById(id),
      staleTime: 5 * 60 * 1000,
      gcTime: 60 * 60 * 1000,
    }),

  followRequests: () =>
    queryOptions({
      queryKey: queryKeys.accounts.followRequests(),
      queryFn: getFollowRequests,
      staleTime: 60 * 1000,
      gcTime: 30 * 60 * 1000,
    }),
}
