import { BarChart3, CheckCircle, AlertTriangle, TrendingUpIcon, Lock } from 'lucide-react' import { useState, useEffect, useMemo } from 'react'; // 1. We need our React tools! import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend } from 'recharts'; import { useTranslation } from 'react-i18next'; import { useAuth } from './context/AuthContext'; import { useNavigate } from 'react-router-dom'; const PERFORMANCE_METRICS = [ { key: "processingSpeed", value: "2.8s avg", width: "75%", color: "bg-gradient-to-r from-blue-500 to-cyan-400" }, { key: "detectionRate", value: "98.4%", width: "98%", color: "bg-gradient-to-r from-green-400 to-emerald-400" }, { key: "systemUptime", value: "99.9%", width: "100%", color: "bg-gradient-to-r from-cyan-400 to-blue-500" } ]; // NOTICE: The hardcoded STATS array has been deleted from here! export default function Statistics(){ const { t } = useTranslation(); const { user } = useAuth(); const navigate = useNavigate(); const [scanHistory, setScanHistory] = useState([]); const [summaryData, setSummaryData] = useState(null); const [isLoading, setIsLoading] = useState(true); useEffect(() => { const fetchStatisticsAndSummary = async () => { try { const apiUrl = import.meta.env.VITE_API_URL || 'http://127.0.0.1:5000'; const token = localStorage.getItem('token'); const headers = { 'Content-Type': 'application/json', ...(token ? { 'Authorization': `Bearer ${token}` } : {}) }; // Fetch history and summary concurrently const [historyRes, summaryRes] = await Promise.all([ fetch(`${apiUrl}/api/statistics/history?page=1&limit=100`, { method: 'GET', headers }), fetch(`${apiUrl}/api/statistics/summary`, { method: 'GET', headers }) ]); if (historyRes.ok) { const result = await historyRes.json(); const fetchedHistory = Array.isArray(result.data) ? result.data : (result.data?.items || result.data?.data || result.data?.history || []); setScanHistory(fetchedHistory); } else { fallbackToLocal(); } if (summaryRes.ok) { const sumResult = await summaryRes.json(); setSummaryData(sumResult.data); } } catch (error) { console.error("Error fetching statistics:", error); fallbackToLocal(); } finally { setIsLoading(false); } }; const fallbackToLocal = () => { const savedHistory = JSON.parse(localStorage.getItem('synthScanHistory')); if (savedHistory && savedHistory.length > 0) { setScanHistory(savedHistory); } }; fetchStatisticsAndSummary(); }, []); // ========================================== // THE REAL-TIME MATH ENGINE // ========================================== const totalScans = summaryData ? summaryData.today_scans : scanHistory.length; const fakeCount = summaryData ? summaryData.detected_fakes : scanHistory.filter((item) => item.result === "Fake" || item.result === "Deepfake").length; // Calculate real based on total - fake, otherwise fallback to array filter const realCount = summaryData ? Math.max(0, totalScans - fakeCount) : scanHistory.filter((item) => item.result === "Real").length; // Calculate the percentages (Preventing "division by zero" if the vault is empty!) const realPercent = totalScans > 0 ? Math.round((realCount / totalScans) * 100) : 0; const fakePercent = totalScans > 0 ? Math.round((fakeCount / totalScans) * 100) : 0; // Use avg_confidence if available, otherwise keep static/calculate const avgConfidenceStr = summaryData?.avg_confidence ? `${summaryData.avg_confidence}%` : "98.4%"; // Helper to generate last 7 days const generateLast7Days = () => { const days = []; for (let i = 6; i >= 0; i--) { const d = new Date(); d.setDate(d.getDate() - i); days.push({ date: d.toISOString().split('T')[0], displayDate: d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }), real: 0, fake: 0, totalConfidence: 0, scanCount: 0, avgConfidence: 0 }); } return days; }; const trendData = useMemo(() => { const days = generateLast7Days(); scanHistory.forEach(item => { if(!item.created_at) return; const dateStr = item.created_at.split('T')[0]; const dayObj = days.find(d => d.date === dateStr); if (dayObj) { if (item.result === "Real") dayObj.real += 1; else dayObj.fake += 1; dayObj.totalConfidence += (item.confidence_score || 0); dayObj.scanCount += 1; } }); // Calculate averages days.forEach(day => { if (day.scanCount > 0) { day.avgConfidence = parseFloat((day.totalConfidence / day.scanCount).toFixed(1)); } }); return days; }, [scanHistory]); // 4. Build the dynamic array right before React draws the screen const dynamicStats = [ { key: "imagesAnalyzed", value: totalScans, icon: BarChart3, iconColor: "text-blue-400", text: t('statistics.allTimeRecords') }, { key: "accuracy", value: avgConfidenceStr, icon: CheckCircle, iconColor: "text-green-400", text: t('statistics.basedOnDataset') }, { key: "realImages", value: realCount, icon: TrendingUpIcon, iconColor: "text-blue-400", text: `${realPercent}% ${t('statistics.ofTotal')}` }, { key: "fakeImages", value: fakeCount, icon: AlertTriangle, iconColor: "text-red-400", text: `${fakePercent}% ${t('statistics.ofTotal')}` } ]; return(
{/* Unauthenticated Overlay */} {!user && (

{t('analysis.lockedTitle')}

{t('analysis.lockedMessage')}

)}

{t('statistics.title')}

{t('statistics.subtitle')}

{/* The 4 top cards */}
{dynamicStats.map(({key, value, icon:Icon, iconColor, text}) =>(
{Icon && }
{t(`statistics.${key}`)}
{value}
{text}
))}
{/* Charts */}
{t('statistics.detectionTrends')}
{t('statistics.confidenceDistribution')}
[`${value}%`, `Avg Confidence (${avgConfidenceStr})`]} />

{t('statistics.performanceMatrix')}

{PERFORMANCE_METRICS.map(({key, value, width, color}) => (
{t(`statistics.${key}`)} {value}
))}
) }