"use client"; import { type Dispatch, useEffect, useRef } from "react"; import type { LoginStatus } from "@/data/schemas/auth"; import { useGuestLoginBootstrap } from "@/hooks/use-guest-login-bootstrap"; import { behaviorAnalytics } from "@/lib/analytics"; import { useActiveCharacterRoutes } from "@/providers/character-provider"; import { useAppNavigator } from "@/router/use-app-navigator"; import type { AuthEvent } from "@/stores/auth/auth-events"; import type { PrivateRoomEvent } from "@/stores/private-room"; import type { PrivateRoomUnlockPaywallRequest } from "@/stores/private-room/private-room-state"; import { useUserDispatch } from "@/stores/user/user-context"; export interface UsePrivateRoomBootstrapFlowInput { authDispatch: Dispatch; hasInitialized: boolean; isAuthLoading: boolean; loginStatus: LoginStatus; roomDispatch: Dispatch; roomStatus: string; } export interface UsePrivateRoomUnlockPaywallNavigationInput { loginStatus: LoginStatus; roomDispatch: Dispatch; unlockPaywallRequest: PrivateRoomUnlockPaywallRequest | null; } export function isPrivateRoomAuthRequired(loginStatus: LoginStatus): boolean { return loginStatus === "guest" || loginStatus === "notLoggedIn"; } export function usePrivateRoomBootstrapFlow({ authDispatch, hasInitialized, isAuthLoading, loginStatus, roomDispatch, roomStatus, }: UsePrivateRoomBootstrapFlowInput): void { const previousLoginStatusRef = useRef(loginStatus); useGuestLoginBootstrap({ dispatch: authDispatch, hasInitialized, isLoading: isAuthLoading, loginStatus, }); useEffect(() => { if (!hasInitialized || isAuthLoading) return; if (loginStatus === "notLoggedIn") return; const previousLoginStatus = previousLoginStatusRef.current; previousLoginStatusRef.current = loginStatus; if (roomStatus === "idle") { roomDispatch({ type: "PrivateRoomInit" }); return; } if (previousLoginStatus !== loginStatus && roomStatus !== "loading") { roomDispatch({ type: "PrivateRoomRefresh" }); } }, [ hasInitialized, isAuthLoading, loginStatus, roomDispatch, roomStatus, ]); } export function usePrivateRoomUnlockPaywallNavigation({ loginStatus, roomDispatch, unlockPaywallRequest, }: UsePrivateRoomUnlockPaywallNavigationInput): void { const navigator = useAppNavigator(); const characterRoutes = useActiveCharacterRoutes(); useEffect(() => { if (!unlockPaywallRequest) return; if (isPrivateRoomAuthRequired(loginStatus)) { navigator.openAuth(characterRoutes.privateRoom); } else { behaviorAnalytics.paywallShown({ entryPoint: "private_album_unlock", triggerReason: "insufficient_credits", }); navigator.openSubscription({ type: "topup", returnTo: "private-room", analytics: { entryPoint: "private_album_unlock", triggerReason: "insufficient_credits", }, }); } roomDispatch({ type: "PrivateRoomUnlockPaywallConsumed" }); }, [ characterRoutes.privateRoom, loginStatus, navigator, roomDispatch, unlockPaywallRequest, ]); } export function usePrivateRoomUnlockSuccessRefresh( unlockSuccessNonce: number, ): void { const userDispatch = useUserDispatch(); const lastUnlockSuccessNonceRef = useRef(0); useEffect(() => { if (unlockSuccessNonce <= lastUnlockSuccessNonceRef.current) return; lastUnlockSuccessNonceRef.current = unlockSuccessNonce; userDispatch({ type: "UserFetch" }); }, [unlockSuccessNonce, userDispatch]); }