import { useState, useCallback } from 'react'; import { useDubs } from '../provider'; import { useAuth } from './useAuth'; import type { ArcadeEntry, StartAttemptResult, SubmitScoreResult } from '../types'; export interface UseArcadeGameResult { entry: ArcadeEntry | null; livesRemaining: number; bestScore: number; loading: boolean; error: Error | null; /** Fetch/refresh the user's entry for this pool */ refreshEntry: () => Promise; /** Start a new life — returns session token to pass to the game */ startAttempt: () => Promise; /** Submit score after game over */ submitScore: (sessionToken: string, score: number, durationMs?: number) => Promise; } export function useArcadeGame(poolId: number | null, maxLives: number = 3): UseArcadeGameResult { const { client } = useDubs(); const { user } = useAuth(); const [entry, setEntry] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const walletAddress = user?.walletAddress || ''; const refreshEntry = useCallback(async () => { if (!poolId || !walletAddress) return; setLoading(true); setError(null); try { const e = await client.getArcadeEntry(poolId, walletAddress); setEntry(e); } catch (err) { // 404 means no entry yet — that's fine if (err instanceof Error && err.message.includes('No entry found')) { setEntry(null); } else { setError(err instanceof Error ? err : new Error(String(err))); } } finally { setLoading(false); } }, [client, poolId, walletAddress]); const startAttempt = useCallback(async (): Promise => { if (!poolId || !walletAddress) throw new Error('Not ready'); setError(null); try { const result = await client.startArcadeAttempt(poolId, walletAddress); return result; } catch (err) { const e = err instanceof Error ? err : new Error(String(err)); setError(e); throw e; } }, [client, poolId, walletAddress]); const submitScore = useCallback(async ( sessionToken: string, score: number, durationMs?: number, ): Promise => { if (!poolId || !walletAddress) throw new Error('Not ready'); setError(null); try { const result = await client.submitArcadeScore(poolId, { walletAddress, sessionToken, score, durationMs, }); // Update local entry state setEntry(prev => prev ? { ...prev, best_score: result.bestScore, lives_used: result.livesUsed, } : prev); return result; } catch (err) { const e = err instanceof Error ? err : new Error(String(err)); setError(e); throw e; } }, [client, poolId, walletAddress]); const livesRemaining = entry ? maxLives - entry.lives_used : maxLives; const bestScore = entry?.best_score || 0; return { entry, livesRemaining, bestScore, loading, error, refreshEntry, startAttempt, submitScore, }; }