import { root } from '@repo/core' import { type GetUserFavoritesInput, type GetUserFavoritesResponse, TemplateSocialController, type UserFavoriteItem, } from '@repo/sdk' import { useCallback, useRef, useState } from 'react' import { type ApiError } from '@/lib/types' import { handleError } from './use-error' type GetUserFavoritesParams = Partial> const DEFAULT_PARAMS = { limit: 20, page: 1, } export const useUserFavorites = (initialParams?: GetUserFavoritesParams) => { const [loading, setLoading] = useState(false) const [loadingMore, setLoadingMore] = useState(false) const [error, setError] = useState(null) const [data, setData] = useState() const currentPageRef = useRef(1) const hasMoreRef = useRef(true) const execute = useCallback(async (params?: GetUserFavoritesParams) => { setLoading(true) setError(null) currentPageRef.current = params?.page || initialParams?.page || 1 const social = root.get(TemplateSocialController) const requestParams: GetUserFavoritesInput = { ...DEFAULT_PARAMS, ...initialParams, ...params, page: params?.page ?? initialParams?.page ?? 1, } const { data, error } = await handleError( async () => await social.getUserFavorites(requestParams), ) if (error) { setError(error) setLoading(false) return { data: undefined, error } } const favorites = data?.favorites || [] const currentPage = requestParams.page || 1 const total = data?.total || 0 const limit = requestParams.limit || 20 const totalPages = Math.ceil(total / limit) hasMoreRef.current = currentPage < totalPages setData(data) setLoading(false) return { data, error: null } }, [initialParams]) const loadMore = useCallback(async () => { if (loadingMore || loading || !hasMoreRef.current) return { data: undefined, error: null } setLoadingMore(true) const nextPage = currentPageRef.current + 1 const social = root.get(TemplateSocialController) const requestParams: GetUserFavoritesInput = { ...DEFAULT_PARAMS, ...initialParams, page: nextPage, } const { data: newData, error } = await handleError( async () => await social.getUserFavorites(requestParams), ) if (error) { setLoadingMore(false) return { data: undefined, error } } const newFavorites = newData?.favorites || [] const total = newData?.total || 0 const limit = requestParams.limit || 20 const totalPages = Math.ceil(total / limit) hasMoreRef.current = nextPage < totalPages currentPageRef.current = nextPage setData((prev) => ({ favorites: [...(prev?.favorites || []), ...newFavorites], total: newData?.total || 0, page: nextPage, limit: requestParams.limit || 20, })) setLoadingMore(false) return { data: newData, error: null } }, [loading, loadingMore, initialParams]) const refetch = useCallback(() => { hasMoreRef.current = true return execute() }, [execute]) return { data, favorites: data?.favorites || [], loading, loadingMore, error, execute, refetch, loadMore, hasMore: hasMoreRef.current, } } export type { UserFavoriteItem }