import React, { useEffect, useRef, useState } from 'react'; import type { BattleResult } from '../types'; interface BattleModalProps { battle: BattleResult | null; onClose: () => void; } export const BattleModal: React.FC = ({ battle, onClose }) => { const [countdown, setCountdown] = useState(5); const [progressPercent, setProgressPercent] = useState(100); // Keep onClose in a ref to decouple the timer effect from callback identity changes const onCloseRef = useRef(onClose); useEffect(() => { onCloseRef.current = onClose; }); // Unique battle key so the 5s timer only restarts when a genuinely new battle arrives const battleKey = battle ? `${battle.winner_party_id}_${battle.defeated_party_id}_${battle.party1_total_score}_${battle.party2_total_score}_${battle.killed_leader_id}` : null; useEffect(() => { if (!battleKey) { setCountdown(5); setProgressPercent(100); return; } const DURATION_MS = 5000; const targetEndTime = Date.now() + DURATION_MS; setCountdown(5); setProgressPercent(100); const timer = window.setInterval(() => { const now = Date.now(); const remainingMs = targetEndTime - now; if (remainingMs <= 0) { window.clearInterval(timer); setCountdown(0); setProgressPercent(0); onCloseRef.current(); return; } const seconds = Math.ceil(remainingMs / 1000); const percent = Math.min(100, Math.max(0, (remainingMs / DURATION_MS) * 100)); setCountdown(seconds); setProgressPercent(percent); }, 100); return () => { window.clearInterval(timer); }; }, [battleKey]); if (!battle) return null; return (
{/* Glowing cyber header banner */}
{/* 5-second automatic progress bar */}
⚔️

PARTY ENGAGEMENT: 3-BOUT D20 CLASH

{battle.party1_name} vs {battle.party2_name}

{/* 3 Bouts Breakdown */}
{battle.bouts.map((bout) => (
BOUT #{bout.bout_number} Winner: {bout.winner_name || 'Tied'}
{/* Party 1 */}
{battle.party1_name}
Str: {bout.party1_strength} × 🎲 {bout.party1_roll} = {bout.party1_score}
{/* Party 2 */}
{battle.party2_name}
Str: {bout.party2_strength} × 🎲 {bout.party2_roll} = {bout.party2_score}
))}
{/* Battle Resolution Summary */}
🏆 VICTORY: {battle.winner_party_name} Bouts: {battle.party1_bouts_won} - {battle.party2_bouts_won}
• Winning Leader {battle.winner_leader_name} receives{' '} +2 points, and all other winning squad members receive{' '} +1 point!
• Defeated Leader {battle.killed_leader_name} receives{' '} -1 point. {battle.absorbed_members.includes(battle.killed_leader_id) ? ( Resistance broken! Surrendered and joined {battle.winner_party_name}. ) : ( Respawned at ({battle.killed_leader_respawn_position.x}, {battle.killed_leader_respawn_position.y}). )}
{battle.absorbed_members.length > 0 && !battle.absorbed_members.includes(battle.killed_leader_id) && (
{battle.absorbed_members.length} surviving bot(s) from the defeated party surrendered and joined {battle.winner_party_name}!
)}
New Squad Size: {battle.new_party_size} bots • Total Strength:{' '} {battle.new_party_strength}
{/* Continue Button with 5s Auto-close Countdown */}
); };