import { invoke } from "@tauri-apps/api/core"; import { listen } from "@tauri-apps/api/event"; import { useCallback, useEffect, useState } from "react"; import type { CloudAuthState, CloudUser } from "@/types"; interface UseCloudAuthReturn { user: CloudUser | null; isLoggedIn: boolean; isLoading: boolean; requestOtp: (email: string, captchaToken: string) => Promise; verifyOtp: (email: string, code: string) => Promise; logout: () => Promise; refreshProfile: () => Promise; } export function useCloudAuth(): UseCloudAuthReturn { const [authState, setAuthState] = useState(null); const [isLoading, setIsLoading] = useState(true); const loadUser = useCallback(async () => { try { const state = await invoke("cloud_get_user"); setAuthState(state); } catch (error) { console.error("Failed to load cloud auth state:", error); setAuthState(null); } finally { setIsLoading(false); } }, []); useEffect(() => { void loadUser(); const unlistenExpired = listen("cloud-auth-expired", () => { setAuthState(null); }); const unlistenChanged = listen("cloud-auth-changed", () => { void loadUser(); }); return () => { void unlistenExpired.then((unlisten) => { unlisten(); }); void unlistenChanged.then((unlisten) => { unlisten(); }); }; }, [loadUser]); const requestOtp = useCallback( (email: string, captchaToken: string): Promise => { return invoke("cloud_request_otp", { email, captchaToken }); }, [], ); const verifyOtp = useCallback( async (email: string, code: string): Promise => { const state = await invoke("cloud_verify_otp", { email, code, }); setAuthState(state); return state; }, [], ); const logout = useCallback(async () => { await invoke("cloud_logout"); setAuthState(null); }, []); const refreshProfile = useCallback(async (): Promise => { const user = await invoke("cloud_refresh_profile"); setAuthState((prev) => prev ? { ...prev, user } : { user, logged_in_at: new Date().toISOString() }, ); return user; }, []); return { user: authState?.user ?? null, isLoggedIn: authState !== null, isLoading, requestOtp, verifyOtp, logout, refreshProfile, }; }