import React, { useState, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import { storyApi } from "../utils/api"; import { useGameSession } from "../hooks/useGameSession"; import { Box, Paper, Typography, Accordion, AccordionSummary, AccordionDetails, Chip, Button, CircularProgress, Alert, Divider, Stack, IconButton, Tooltip, Tab, Tabs, Grid, } from "@mui/material"; import { ExpandMore as ExpandMoreIcon, Refresh as RefreshIcon, BugReport as BugReportIcon, Timer as TimerIcon, LocationOn as LocationIcon, Psychology as PsychologyIcon, History as HistoryIcon, Image as ImageIcon, TextFields as TextFieldsIcon, List as ListIcon, Palette as PaletteIcon, Category as CategoryIcon, AccessTime as AccessTimeIcon, ArrowForward as ArrowForwardIcon, } from "@mui/icons-material"; import { DebugConsole } from "../components/DebugConsole"; import { Metric } from "../components/Metric"; import { UniverseView } from "../components/UniverseView"; import { UniverseMetrics } from "../components/UniverseMetrics"; const Debug = () => { const navigate = useNavigate(); const [gameState, setGameState] = useState(null); const [currentStory, setCurrentStory] = useState(null); const [error, setError] = useState(null); const [currentTab, setCurrentTab] = useState(0); const [expandedPanel, setExpandedPanel] = useState("current"); const [isLoading, setIsLoading] = useState(false); const historyContainerRef = React.useRef(null); const { sessionId, universe, isLoading: isSessionLoading, error: sessionError, } = useGameSession(); const handleTabChange = (event, newValue) => { setCurrentTab(newValue); }; const handlePanelChange = (panel) => (event, isExpanded) => { setExpandedPanel(isExpanded ? panel : false); }; // Initialize game const initializeGame = async () => { try { setIsLoading(true); const response = await storyApi.start(sessionId); // Construire l'entrée d'historique initiale const initialHistoryEntry = { segment: response.story_text, player_choice: null, available_choices: response.choices.map((choice) => choice.text), time: response.time, location: response.location, previous_choice: response.previous_choice, }; setGameState({ universe_style: universe?.style, universe_genre: universe?.genre, universe_epoch: universe?.epoch, universe_macguffin: universe?.macguffin, universe_selected_artist: universe?.style?.selected_artist, story_beat: 0, story_history: [initialHistoryEntry], }); setCurrentStory(response); } catch (err) { setError(err.message); } finally { setIsLoading(false); } }; // Make a choice const makeChoice = async (choiceIndex) => { try { setIsLoading(true); const response = await storyApi.makeChoice(choiceIndex + 1, sessionId); setCurrentStory(response); // Construire l'entrée d'historique const historyEntry = { segment: response.story_text, player_choice: currentStory.choices[choiceIndex].text, available_choices: currentStory.choices.map((choice) => choice.text), time: response.time, location: response.location, previous_choice: response.previous_choice, }; setGameState((prev) => ({ ...prev, story_history: [...(prev.story_history || []), historyEntry], story_beat: (prev.story_beat || 0) + 1, universe_macguffin: prev.universe_macguffin, })); } catch (err) { setError(err.message); } finally { setIsLoading(false); } }; useEffect(() => { if (sessionId && !isSessionLoading && !gameState) { initializeGame(); } }, [sessionId, isSessionLoading, gameState]); // Ajout de l'effet pour le défilement automatique useEffect(() => { if (historyContainerRef.current && gameState?.story_history?.length > 0) { historyContainerRef.current.scrollTop = historyContainerRef.current.scrollHeight; } }, [gameState?.story_history]); // Render history entries const renderHistoryEntry = (entry, idx) => ( {/* Previous Choice (if any) */} {entry.previous_choice && ( Choix précédent : {entry.previous_choice} )} {/* Time and Location */} {entry.time} {entry.location} {/* Story Text */} {entry.segment} {/* Available Choices */} {entry.available_choices && entry.available_choices.length > 0 && ( Choix disponibles : {entry.available_choices.map((choice, choiceIdx) => ( ))} )} ); if (error || sessionError) { return ( window.location.reload()} > Restart } > {error || sessionError} ); } if (isSessionLoading || !gameState) { return ( ); } return ( {/* Header - plus compact */} Debug Mode window.location.reload()} size="small"> } label="Current State" /> } label="Universe" /> } label="Debug" /> {/* Content - scrollable */} {/* Current State Tab */} {currentTab === 0 && currentStory && ( {/* Universe Info & Game State */} {/* Universe Info */} {/* Game State */} Game State } label="Time" value={currentStory.time} color="secondary" /> } label="Location" value={currentStory.location} color="secondary" /> } label="Story Beat" value={gameState.story_beat} color="secondary" /> Story in Progress Death: {currentStory.is_death ? "Yes" : "No"} Victory:{" "} {currentStory.is_victory ? "Yes" : "No"} {/* Story and Choices Row */} {/* Story Content */} Story {currentStory.story_text} {/* Interactive Choices */} Available Choices {currentStory.choices && currentStory.choices.length > 0 ? ( currentStory.choices.map((choice, idx) => ( )) ) : ( No choices available )} {/* Story History */} Story History {gameState.story_history.length > 0 ? ( gameState.story_history.map((entry, idx) => renderHistoryEntry(entry, idx) ) ) : ( No history available )} {/* Image Prompts */} Image Prompts {currentStory.image_prompts.map((prompt, idx) => ( {idx + 1}. {prompt} ))} )} {/* Universe Tab */} {currentTab === 1 && } {/* Debug Tab */} {currentTab === 2 && ( )} ); }; export default Debug;