import { useEffect, useState, useRef, useCallback } from 'react'; import { supabase } from '@/integrations/supabase/client'; interface ModerationStats { pendingSubmissions: number; openReports: number; flaggedContent: number; } interface UseModerationStatsOptions { onStatsChange?: (stats: ModerationStats) => void; enabled?: boolean; pollingEnabled?: boolean; pollingInterval?: number; realtimeEnabled?: boolean; } export const useModerationStats = (options: UseModerationStatsOptions = {}) => { const { onStatsChange, enabled = true, pollingEnabled = true, pollingInterval = 60000, // Reduced to 60 seconds realtimeEnabled = true } = options; const [stats, setStats] = useState({ pendingSubmissions: 0, openReports: 0, flaggedContent: 0, }); const [isLoading, setIsLoading] = useState(true); const [isInitialLoad, setIsInitialLoad] = useState(true); const [lastUpdated, setLastUpdated] = useState(null); const onStatsChangeRef = useRef(onStatsChange); const statsDebounceRef = useRef(null); // Update ref when callback changes useEffect(() => { onStatsChangeRef.current = onStatsChange; }, [onStatsChange]); const fetchStats = useCallback(async (silent = false) => { if (!enabled) return; try { // Only show loading on initial load if (!silent) { setIsLoading(true); } const [submissionsResult, reportsResult, reviewsResult] = await Promise.all([ supabase .from('content_submissions') .select('id', { count: 'exact', head: true }) .eq('status', 'pending'), supabase .from('reports') .select('id', { count: 'exact', head: true }) .eq('status', 'pending'), supabase .from('reviews') .select('id', { count: 'exact', head: true }) .eq('moderation_status', 'flagged'), ]); const newStats = { pendingSubmissions: submissionsResult.count || 0, openReports: reportsResult.count || 0, flaggedContent: reviewsResult.count || 0, }; setStats(newStats); setLastUpdated(new Date()); onStatsChangeRef.current?.(newStats); } catch (error) { console.error('Error fetching moderation stats:', error); } finally { // Only clear loading if it was set if (!silent) { setIsLoading(false); } if (isInitialLoad) { setIsInitialLoad(false); } } }, [enabled, isInitialLoad]); // Initial fetch useEffect(() => { if (enabled) { fetchStats(false); // Show loading } }, [enabled, fetchStats]); // Debounced stats fetch to prevent rapid-fire updates const debouncedFetchStats = useCallback(() => { if (statsDebounceRef.current) { clearTimeout(statsDebounceRef.current); } statsDebounceRef.current = setTimeout(() => { fetchStats(true); // Silent refresh }, 2000); // 2 second debounce to reduce flashing }, [fetchStats]); // Realtime subscription - only trigger on INSERT of new pending items useEffect(() => { if (!enabled || !realtimeEnabled) return; const channel = supabase .channel('moderation-stats-realtime') .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'content_submissions', filter: 'status=eq.pending' }, debouncedFetchStats) .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'reports', filter: 'status=eq.pending' }, debouncedFetchStats) .on('postgres_changes', { event: '*', schema: 'public', table: 'reviews', filter: 'moderation_status=eq.flagged' }, debouncedFetchStats) .subscribe(); return () => { supabase.removeChannel(channel); if (statsDebounceRef.current) { clearTimeout(statsDebounceRef.current); } }; }, [enabled, realtimeEnabled, debouncedFetchStats]); // Polling (fallback when realtime is disabled) useEffect(() => { if (!enabled || !pollingEnabled || realtimeEnabled || isInitialLoad) return; const interval = setInterval(() => { fetchStats(true); // Silent refresh }, pollingInterval); return () => { clearInterval(interval); }; }, [enabled, pollingEnabled, realtimeEnabled, pollingInterval, fetchStats, isInitialLoad]); return { stats, refresh: fetchStats, isLoading, lastUpdated }; };