import { type BrokerageAccountCard, brokerageAccountCards, useBrokerageAccounts, } from "@/entities/brokerage-account"; import { useScreenSync } from "@/features/tbank-connection"; import { ApiErrorCode, apiErrorCode, isApiErrorCode } from "@/shared/api"; import { useInitialAvailability } from "@/shared/lib"; type AccountsPageViewModel = | { accounts: BrokerageAccountCard[]; meta: NonNullable["meta"]>; state: "loaded" } | { code?: string; state: "error" } | { state: "empty" } | { state: "loading" }; function isAccountsAccessFailure(code?: string) { return isApiErrorCode(code, ApiErrorCode.InvalidTbankToken) || isApiErrorCode(code, ApiErrorCode.TbankNotConnected); } function useAccountsPageViewModel(): AccountsPageViewModel { const accounts = useBrokerageAccounts(); useScreenSync({ screen: "accounts" }, [accounts]); const code = apiErrorCode(accounts.error); const isAccessFailure = isAccountsAccessFailure(code); const hasResult = !!accounts.data && !!accounts.meta && !(accounts.meta.completeness === "incomplete" && accounts.data.length === 0); const availability = useInitialAvailability({ hasContent: hasResult, identity: "accounts", isError: accounts.isError || accounts.meta?.lastAttempt.state === "failed", isFetching: accounts.isFetching, }); if (isAccessFailure) return { code, state: "error" as const }; if (!hasResult || !accounts.data) return { state: availability === "unavailable" ? "error" : "loading", } as const; if (accounts.data.length === 0) return { state: "empty" as const, }; const meta = accounts.meta; if (!meta) return { state: "loading" as const }; return { accounts: brokerageAccountCards(accounts.data, meta.dependencies), meta, state: "loaded" as const, }; } export { useAccountsPageViewModel };