"use client"; import { useRouter } from "next/navigation"; import { NavigationStorage } from "@/data/storage/navigation"; import { getDefaultPayChannelForCountryCode } from "@/lib/payment/default_pay_channel"; import { useAuthState } from "@/stores/auth/auth-context"; import { useUserState } from "@/stores/user/user-context"; import { ROUTE_BUILDERS, ROUTES, type Route, } from "./routes"; import { isAuthenticatedUser as resolveIsAuthenticatedUser, resolveAuthenticatedNavigation, } from "./navigation-resolver"; import type { OpenSubscriptionForPendingUnlockInput, OpenSubscriptionInput, StartMessageUnlockInput, } from "./navigation-types"; export interface AppNavigator { push: (href: string, options?: { scroll?: boolean }) => void; replace: (href: string, options?: { scroll?: boolean }) => void; openAuth: (redirectTo?: string) => void; openSubscription: (input: OpenSubscriptionInput) => void; startMessageUnlock: (input: StartMessageUnlockInput) => void; openSubscriptionForPendingUnlock: ( input: OpenSubscriptionForPendingUnlockInput, ) => void; getDefaultPayChannel: () => ReturnType; isAuthenticatedUser: boolean; } export function useAppNavigator(): AppNavigator { const router = useRouter(); const authState = useAuthState(); const userState = useUserState(); const isAuthenticatedUser = resolveIsAuthenticatedUser(authState.loginStatus); function push(href: string, options?: { scroll?: boolean }): void { router.push(href, options); } function replace(href: string, options?: { scroll?: boolean }): void { router.replace(href, options); } function openAuth(redirectTo: string = ROUTES.chat): void { router.push(ROUTE_BUILDERS.authWithRedirect(redirectTo)); } function getDefaultPayChannel() { return getDefaultPayChannelForCountryCode(userState.currentUser?.countryCode); } function openSubscription({ type, payChannel = getDefaultPayChannel(), returnTo = null, replace: shouldReplace = false, }: OpenSubscriptionInput): void { const target = ROUTE_BUILDERS.subscription(type, { payChannel, returnTo: returnTo ?? undefined, }); const nextUrl = resolveAuthenticatedNavigation({ loginStatus: authState.loginStatus, targetUrl: target, }); if (shouldReplace) { router.replace(nextUrl); return; } router.push(nextUrl); } function startMessageUnlock({ messageId, kind, returnUrl, stage = "auth", onAuthenticated, }: StartMessageUnlockInput): void { if (isAuthenticatedUser) { onAuthenticated(); return; } void (async () => { await NavigationStorage.savePendingChatUnlock({ messageId, kind, returnUrl, stage, }); router.push(ROUTE_BUILDERS.authWithRedirect(returnUrl)); })(); } function openSubscriptionForPendingUnlock({ messageId, kind, returnUrl, type, payChannel = getDefaultPayChannel(), }: OpenSubscriptionForPendingUnlockInput): void { void (async () => { await NavigationStorage.savePendingChatUnlock({ messageId, kind, returnUrl, stage: "payment", }); openSubscription({ type, payChannel, returnTo: "chat", }); })(); } return { push, replace, openAuth, openSubscription, startMessageUnlock, openSubscriptionForPendingUnlock, getDefaultPayChannel, isAuthenticatedUser, }; } export type { Route };