import React, { createContext, useContext, useState, useCallback } from "react"; import { useUser, useAuth } from "@clerk/clerk-expo"; import { getUserStatistics } from "../api/statistics"; import type { UserStatisticsResponse } from "../api/types"; import log from "../utils/logger"; interface StatisticsContextValue { statistics: UserStatisticsResponse | null; loading: boolean; error: Error | null; refetchStatistics: () => Promise; forceRefresh: () => Promise; clearCache: () => void; } const StatisticsContext = createContext( undefined, ); export function StatisticsProvider({ children, }: { children: React.ReactNode; }) { const { user } = useUser(); const { getToken } = useAuth(); const [statistics, setStatistics] = useState( null, ); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [lastFetchTime, setLastFetchTime] = useState(0); // Cache statistics for 30 seconds to avoid duplicate calls const CACHE_DURATION = 30000; // 30 seconds const refetchStatistics = useCallback(async () => { if (!user?.id) return; // Check if we have recent cached data const now = Date.now(); if (statistics && now - lastFetchTime < CACHE_DURATION) { log.debug("Using cached statistics", { age: now - lastFetchTime, cacheRemaining: CACHE_DURATION - (now - lastFetchTime), }); return; } try { setLoading(true); setError(null); log.debug("Fetching fresh statistics", { userId: user.id }); const token = await getToken(); const stats = await getUserStatistics(user.id, token); setStatistics(stats); setLastFetchTime(now); log.debug("Statistics fetched and cached", { userId: user.id, hasWeeklyTrend: !!stats.weeklyTrend, weeklyTrendLength: stats.weeklyTrend?.length || 0, weeklyTrendSample: stats.weeklyTrend?.[0], stats, }); } catch (err) { const error = err instanceof Error ? err : new Error(String(err)); log.error("Failed to fetch statistics", error); setError(error); } finally { setLoading(false); } }, [user?.id, getToken, statistics, lastFetchTime]); const clearCache = useCallback(() => { setStatistics(null); setLastFetchTime(0); setError(null); log.debug("Statistics cache cleared"); }, []); const forceRefresh = useCallback(async () => { if (!user?.id) return; try { setLoading(true); setError(null); log.debug("Force fetching statistics", { userId: user.id }); const token = await getToken(); const stats = await getUserStatistics(user.id, token); setStatistics(stats); setLastFetchTime(Date.now()); log.debug("Statistics force fetched and cached", { userId: user.id, hasWeeklyTrend: !!stats.weeklyTrend, weeklyTrendLength: stats.weeklyTrend?.length || 0, weeklyTrendSample: stats.weeklyTrend?.[0], stats, }); } catch (err) { const error = err instanceof Error ? err : new Error(String(err)); log.error("Failed to force fetch statistics", error); setError(error); } finally { setLoading(false); } }, [user?.id, getToken]); return ( {children} ); } export function useStatistics() { const context = useContext(StatisticsContext); if (context === undefined) { throw new Error("useStatistics must be used within a StatisticsProvider"); } return context; }