import { hashKey, useQueryClient } from "@tanstack/react-query"; import { useEffect, useState } from "react"; import { ApiErrorCode, apiErrorCode, isApiErrorCode } from "@/shared/api"; import { type BrokerageOperationsQuery, brokerageOperationsQueryOptions, useBrokerageOperations, } from "../api/useBrokerageOperations"; function useBrokerageOperationHistory( accountId: string | undefined, firstPage: Omit, ) { const { queryKey } = brokerageOperationsQueryOptions(accountId, firstPage); const scope = hashKey(queryKey); const [pagination, setPagination] = useState<{ cursors: string[]; scope: string; }>({ cursors: [], scope }); const cursors = pagination.scope === scope ? pagination.cursors : []; const client = useQueryClient(); const operations = useBrokerageOperations(accountId, { ...firstPage, cursor: cursors.at(-1), }); const isInvalidCursor = isApiErrorCode( apiErrorCode(operations.error), ApiErrorCode.InvalidOperationsCursor, ); const isRecoveringInvalidCursor = cursors.length > 0 && isInvalidCursor; const reset = () => setPagination({ cursors: [], scope }); useEffect(() => { if (!isRecoveringInvalidCursor) return; const timeout = setTimeout(() => { setPagination({ cursors: [], scope }); void client.invalidateQueries({ exact: true, queryKey }); }, 0); return () => clearTimeout(timeout); }, [client, isRecoveringInvalidCursor, queryKey, scope]); const retry = (retryScreen: () => unknown) => { if (isInvalidCursor) { reset(); void client.invalidateQueries({ exact: true, queryKey, }); } else void retryScreen(); }; return { hasPrevious: cursors.length > 0, isRecoveringInvalidCursor, onNext: () => { if (operations.data?.nextCursor) setPagination({ cursors: [...cursors, operations.data.nextCursor], scope, }); }, onPrevious: () => setPagination({ cursors: cursors.slice(0, -1), scope }), operations, reset, retry, }; } export { useBrokerageOperationHistory };