import React, { useState, useEffect, useRef } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Trophy, ArrowLeft, RefreshCw, Zap, Target, Activity, ShieldCheck, Share2 } from 'lucide-react'; import { Button } from './Button'; import { StorageService } from '../../services/storageService'; interface GameShellProps { gameId: string; title: string; onExit: () => void; children: (props: { onGameOver: (score: number, stats?: any) => void }) => React.ReactNode; } type GameState = 'intro' | 'countdown' | 'playing' | 'results'; export const GameShell: React.FC = ({ gameId, title, onExit, children }) => { const [gameState, setGameState] = useState('intro'); const [countdown, setCountdown] = useState(3); const [finalScore, setFinalScore] = useState(0); const [gameStats, setGameStats] = useState(null); // Timer Refs const startTimeRef = useRef(0); useEffect(() => { // Capture start time when component mounts (or effectively when game starts playing) // We'll set the actual start time when state changes to 'playing' return () => { // Cleanup: save duration if exiting abruptly while playing // Note: React's strict mode might double trigger, but storage append is safe-ish }; }, []); // --- START SEQUENCER --- const startCountdown = () => { setGameState('countdown'); let timer = 3; const interval = setInterval(() => { timer--; if (timer === 0) { clearInterval(interval); setGameState('playing'); startTimeRef.current = Date.now(); } else { setCountdown(timer); } }, 800); }; const saveSessionDuration = () => { if (startTimeRef.current > 0) { const duration = Math.floor((Date.now() - startTimeRef.current) / 1000); if (duration > 0) { StorageService.saveGameSession(gameId, duration); } startTimeRef.current = 0; // Reset } }; const handleExit = () => { if (gameState === 'playing') { saveSessionDuration(); } onExit(); }; // --- SCORE HANDLER --- const handleGameOver = async (score: number, stats?: any) => { saveSessionDuration(); // Save time immediately on game over setFinalScore(score); setGameStats(stats); setGameState('results'); try { const profile = await StorageService.getProfile(); if (profile) { // Log transaction properly using addPoints await StorageService.addPoints(score, score * 2, 'game_reward', `Arcade: ${title}`); // Track high score for specific game const highScores = profile.highScores || {}; if (!highScores[gameId] || score > highScores[gameId]) { // Manually update high score field as addPoints only handles karma/xp const newHighScores = { ...highScores, [gameId]: score }; await StorageService.updateProfile({ highScores: newHighScores }); } } } catch (err) { console.error("Failed to sync neural data:", err); } }; const restartGame = () => { setCountdown(3); setFinalScore(0); setGameStats(null); startCountdown(); }; return (
{/* --- STATE: INTRO SCREEN --- */} {gameState === 'intro' && (

Initializing Protocol

{title}

)} {/* --- STATE: COUNTDOWN --- */} {gameState === 'countdown' && ( {countdown} )} {/* --- STATE: PLAYING --- */} {gameState === 'playing' && ( {/* Inject the Game Component here */} {children({ onGameOver: handleGameOver })} )} {/* --- STATE: RESULTS --- */} {gameState === 'results' && (
{/* Background Glow */}

Session Complete

Performance Synced

{/* Score Grid */}

Neural Points

{finalScore.toLocaleString()}

Precision

{gameStats?.accuracy || '98'}%

)}
); };