/**
 * @license
 * SPDX-License-Identifier: Apache-2.0
 */
import { useState, useEffect, useRef } from 'react';
import ReactDOM from 'react-dom/client';
import { allGameQuestions, Question, Option } from './questions';
import { phishingEmails, ctfChallenges, PhishingEmail, CtfChallenge, pentestChallenges, PentestChallenge, incidentResponseChallenges, IncidentResponseChallenge, threatModelingChallenges, ThreatModelingChallenge, Threat } from './game-data';

const DESIRED_QUESTIONS_PER_GAME = 10;
const MINIMUM_VALID_QUESTIONS_TO_START = 8;
const GAME_DESCRIPTION = "Welcome to Cyber Games! Sharpen your cybersecurity knowledge with this challenging quiz. Test your skills, learn from your mistakes with detailed explanations, and aim for a perfect score. Are you ready to prove your cyber expertise?";

type GameState = 'welcome' | 'playing' | 'results';
type AppView = 'landing' | 'quiz' | 'phishing' | 'ctf' | 'pentest' | 'incident' | 'threat';

// --- UTILITY FUNCTIONS ---
function shuffleArray<T>(array: T[]): T[] {
  const newArray = [...array];
  for (let i = newArray.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [newArray[i], newArray[j]] = [newArray[j], newArray[i]];
  }
  return newArray;
}

function isValidQuestion(question: Question | undefined | null): question is Question {
  if (!question) return false;
  const { questionText, options, correctAnswerId, explanation } = question;
  if (!questionText || !explanation) return false;
  if (!options || options.length < 2) return false;
  if (!options.every(opt => opt && typeof opt.id === 'string' && typeof opt.text === 'string')) return false;
  return !(!correctAnswerId || !options.some(opt => opt.id === correctAnswerId));
}

// --- GAME COMPONENTS ---

// 1. CYBER QUIZ (Original Game)
interface AnswerRecord {
  question: Question;
  userAnswerId: string;
  isCorrect: boolean;
}

function QuizGame({ onGoHome }: { onGoHome: () => void }) {
  const [gameState, setGameState] = useState<GameState>('welcome');
  const [currentQuestions, setCurrentQuestions] = useState<Question[]>([]);
  const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
  const [score, setScore] = useState(0);
  const [selectedAnswerId, setSelectedAnswerId] = useState<string | null>(null);
  const [userAnswers, setUserAnswers] = useState<AnswerRecord[]>([]);
  const [feedback, setFeedback] = useState<string | null>(null);
  const [shuffledDisplayOptions, setShuffledDisplayOptions] = useState<Option[]>([]);
  const [optionLabelMap, setOptionLabelMap] = useState<{ [key: string]: string }>({});

  const questionTitleRef = useRef<HTMLHeadingElement>(null);

  useEffect(() => {
    if (gameState === 'playing' && currentQuestions.length > 0) {
      const currentQ = currentQuestions[currentQuestionIndex];
      if (isValidQuestion(currentQ)) {
        const newShuffledOptions = shuffleArray([...currentQ.options]);
        setShuffledDisplayOptions(newShuffledOptions);
        const newLabelMap: { [key: string]: string } = {};
        newShuffledOptions.forEach((option, index) => {
          newLabelMap[['A', 'B', 'C', 'D'][index]] = option.id;
        });
        setOptionLabelMap(newLabelMap);
        setSelectedAnswerId(null);
        setFeedback(null);
        questionTitleRef.current?.focus();
      } else {
        handleNextQuestion();
      }
    }
  }, [currentQuestionIndex, currentQuestions, gameState]);

  const startGame = (questions: Question[]) => {
    setFeedback(null);
    const validGameQuestions = questions.filter(isValidQuestion);
    if (validGameQuestions.length < MINIMUM_VALID_QUESTIONS_TO_START) {
      setFeedback(`Could not prepare enough valid questions. Please try again.`);
      setGameState('welcome');
      return;
    }
    setCurrentQuestions(validGameQuestions);
    setCurrentQuestionIndex(0);
    setScore(0);
    setUserAnswers([]);
    setGameState('playing');
  };

  const startClassicGame = () => {
    startGame(shuffleArray(allGameQuestions).slice(0, DESIRED_QUESTIONS_PER_GAME));
  };
  

  const handleAnswerSelect = (displayedLabel: string) => {
    if (selectedAnswerId !== null) return;
    setSelectedAnswerId(displayedLabel);
    const originalSelectedOptionId = optionLabelMap[displayedLabel];
    const currentQ = currentQuestions[currentQuestionIndex];
    const isCorrect = originalSelectedOptionId === currentQ.correctAnswerId;

    if (isCorrect) {
      setScore(prev => prev + 1);
      setFeedback('Correct!');
    } else {
      const correctOption = currentQ.options.find(opt => opt.id === currentQ.correctAnswerId);
      setFeedback(`Incorrect. The correct answer was "${correctOption?.text}".`);
    }
    setUserAnswers(prev => [...prev, { question: currentQ, userAnswerId: originalSelectedOptionId, isCorrect }]);
  };

  const handleNextQuestion = () => {
    if (currentQuestionIndex < currentQuestions.length - 1) {
      setCurrentQuestionIndex(prev => prev + 1);
    } else {
      setGameState('results');
    }
  };
  
  const restartGame = () => {
      setGameState('welcome');
      setFeedback(null);
  };

  if (gameState === 'welcome') {
    return (
      <div className="container welcome-screen">
        <h2>Cybersecurity Quiz</h2>
        <p className="game-description">{GAME_DESCRIPTION}</p>
        {feedback && <p className="feedback feedback-incorrect" aria-live="polite">{feedback}</p>}
        <div className="welcome-buttons">
            <button onClick={startClassicGame} className="start-button">Start Quiz</button>
        </div>
      </div>
    );
  }

  if (gameState === 'results') {
    const incorrectAnswers = userAnswers.filter(ans => !ans.isCorrect);
    return (
      <section className="container results-screen">
        <h2>Game Over!</h2>
        <h3>Your Score: {score} / {currentQuestions.length}</h3>
        {incorrectAnswers.length > 0 && (
          <div className="incorrect-answers-review">
            <h4>Review Your Mistakes:</h4>
            <ul>
              {incorrectAnswers.map((ansRecord, index) => {
                const userAnswerText = ansRecord.question.options.find(opt => opt.id === ansRecord.userAnswerId)?.text || "N/A";
                const correctAnswerText = ansRecord.question.options.find(opt => opt.id === ansRecord.question.correctAnswerId)?.text || "N/A";
                return (
                  <li key={index} className="review-item">
                    <p><strong>Question:</strong> {ansRecord.question.questionText}</p>
                    <p><strong>Your Answer:</strong> <span className="user-answer">{userAnswerText}</span></p>
                    <p><strong>Correct Answer:</strong> <span className="correct-answer-text">{correctAnswerText}</span></p>
                    <p><strong>Explanation:</strong> {ansRecord.question.explanation}</p>
                  </li>
                );
              })}
            </ul>
          </div>
        )}
        <button onClick={restartGame} className="play-again-button">Play Again</button>
      </section>
    );
  }
  
  const currentQ = currentQuestions[currentQuestionIndex];
  if (!currentQ) {
      return <div className="container"><p>Loading question...</p></div>;
  }

  return (
    <section className="container game-screen">
      <div className="game-header">
        <span>Question {currentQuestionIndex + 1}/{currentQuestions.length}</span>
        <span>Score: {score}</span>
      </div>
      <h2 tabIndex={-1} ref={questionTitleRef}>{currentQ.questionText}</h2>
      <div className="options-container">
        {shuffledDisplayOptions.map((option, index) => {
          const displayedLabel = ['A', 'B', 'C', 'D'][index];
          let buttonClass = 'option-button';
          if (selectedAnswerId !== null) {
            const isSelected = selectedAnswerId === displayedLabel;
            const isCorrect = option.id === currentQ.correctAnswerId;
            if(isCorrect) buttonClass += ' reveal-correct';
            else if (isSelected && !isCorrect) buttonClass += ' incorrect';
            else buttonClass += ' disabled-opaque';
          }
          return (
            <button key={option.id} onClick={() => handleAnswerSelect(displayedLabel)} disabled={selectedAnswerId !== null} className={buttonClass}>
              {displayedLabel}) {option.text}
            </button>
          );
        })}
      </div>
      {feedback && <p className={`feedback ${feedback.startsWith('Correct') ? 'feedback-correct' : 'feedback-incorrect'}`} aria-live="polite">{feedback}</p>}
      {selectedAnswerId !== null && (
        <button onClick={handleNextQuestion} className="next-button">
          {currentQuestionIndex === currentQuestions.length - 1 ? 'Show Results' : 'Next Question'}
        </button>
      )}
    </section>
  );
}

// 2. SPOT THE PHISH
function PhishingGame({ onGoHome }: { onGoHome: () => void }) {
    const [gameState, setGameState] = useState<GameState>('welcome');
    const [emails, setEmails] = useState<PhishingEmail[]>([]);
    const [currentIndex, setCurrentIndex] = useState(0);
    const [score, setScore] = useState(0);
    const [feedback, setFeedback] = useState<string | null>(null);
    const [isAnswered, setIsAnswered] = useState(false);

    const startGame = () => {
        setEmails(shuffleArray(phishingEmails).slice(0, 10));
        setCurrentIndex(0);
        setScore(0);
        setFeedback(null);
        setIsAnswered(false);
        setGameState('playing');
    };
    
    const handleAnswer = (userChoice: boolean) => {
        if (isAnswered) return;
        const correctChoice = emails[currentIndex].isPhishing;
        if (userChoice === correctChoice) {
            setFeedback('Correct!');
            setScore(s => s + 1);
        } else {
            setFeedback('Incorrect!');
        }
        setIsAnswered(true);
    };
    
    const handleNext = () => {
        if (currentIndex < emails.length - 1) {
            setCurrentIndex(i => i + 1);
            setIsAnswered(false);
            setFeedback(null);
        } else {
            setGameState('results');
        }
    };

    if (gameState === 'welcome') {
        return (
            <div className="container welcome-screen">
                <h2>Spot the Phish</h2>
                <p className="game-description">Can you tell a legitimate email from a clever fake? Analyze each email for red flags and make your call. Your security depends on it!</p>
                <button onClick={startGame} className="start-button">Start Analyzing</button>
            </div>
        );
    }
    
    if (gameState === 'results') {
        return (
            <div className="container results-screen">
                <h2>Analysis Complete!</h2>
                <h3>Your Score: {score} / {emails.length}</h3>
                <p>Phishing attacks are common. Staying vigilant is key to protecting your data.</p>
                <button onClick={startGame} className="play-again-button">Play Again</button>
            </div>
        );
    }
    
    const currentEmail = emails[currentIndex];

    return (
        <div className="container">
            <div className="game-header">
                <span>Email {currentIndex + 1}/{emails.length}</span>
                <span>Score: {score}</span>
            </div>
            <div className="phishing-container">
                <h2>{currentEmail.subject}</h2>
                <div className="phishing-header">
                    <p><span>From:</span> {currentEmail.sender}</p>
                    <p><span>To:</span> you@example.com</p>
                </div>
                <div className="phishing-body" dangerouslySetInnerHTML={{ __html: currentEmail.body }}></div>
            </div>
            {!isAnswered ? (
                <div className="phishing-options">
                    <button onClick={() => handleAnswer(false)} className="option-button" style={{backgroundColor: 'var(--success-color)'}}>Legitimate</button>
                    <button onClick={() => handleAnswer(true)} className="option-button" style={{backgroundColor: 'var(--error-color)'}}>Phishing</button>
                </div>
            ) : (
                <div>
                    <p className={`feedback ${feedback === 'Correct!' ? 'feedback-correct' : 'feedback-incorrect'}`} aria-live="polite">
                        {feedback} This email is <strong>{currentEmail.isPhishing ? 'a phishing attempt' : 'legitimate'}</strong>.
                    </p>
                    <div className="review-item">
                       <p><strong>Explanation:</strong> {currentEmail.explanation}</p>
                    </div>
                    <button onClick={handleNext} className="next-button">
                        {currentIndex < emails.length - 1 ? 'Next Email' : 'Show Results'}
                    </button>
                </div>
            )}
        </div>
    );
}

// 3. CAPTURE THE FLAG
function CtfGame({ onGoHome }: { onGoHome: () => void }) {
    const [solved, setSolved] = useState<number[]>([]);
    const [activeChallenge, setActiveChallenge] = useState<CtfChallenge | null>(null);
    const [flagInput, setFlagInput] = useState('');
    const [feedback, setFeedback] = useState('');

    const categories = Array.from(new Set(ctfChallenges.map(c => c.category))).sort();
    const [selectedCategory, setSelectedCategory] = useState<string>(categories[0]);

    const handleSelectChallenge = (challenge: CtfChallenge) => {
        if (solved.includes(challenge.id)) return;
        setActiveChallenge(challenge);
        setFeedback('');
        setFlagInput('');
    };

    const handleSubmitFlag = (e: React.FormEvent) => {
        e.preventDefault();
        if (!activeChallenge) return;

        const trimmedInput = flagInput.trim();
        const isCorrect = 
            trimmedInput.toLowerCase() === activeChallenge.flag.toLowerCase() || 
            `flag{${trimmedInput}}`.toLowerCase() === activeChallenge.flag.toLowerCase();

        if (isCorrect) {
            setFeedback('Correct! Flag captured!');
            setSolved(s => [...s, activeChallenge.id]);
            setTimeout(() => {
                setActiveChallenge(null);
            }, 1500);
        } else {
            setFeedback('Incorrect flag. Keep trying!');
        }
    };
    
    if (activeChallenge) {
        return (
            <div className="container">
                <button onClick={() => setActiveChallenge(null)} className="back-button">{'< Back to Challenges'}</button>
                <h2>{activeChallenge.title}</h2>
                <p><strong>Category:</strong> {activeChallenge.category} | <strong>Difficulty:</strong> {activeChallenge.difficulty}</p>
                <div className="review-item">
                    <p dangerouslySetInnerHTML={{ __html: activeChallenge.description }}></p>
                </div>
                <form onSubmit={handleSubmitFlag}>
                    <input 
                        type="text" 
                        value={flagInput}
                        onChange={(e) => setFlagInput(e.target.value)}
                        className="ctf-flag-input"
                        placeholder="flag{...}"
                        aria-label="Enter flag"
                    />
                    <button type="submit" className="next-button" style={{marginTop: '15px'}}>Submit</button>
                </form>
                {feedback && <p className={`feedback ${feedback.startsWith('Correct') ? 'feedback-correct' : 'feedback-incorrect'}`}>{feedback}</p>}
                 <button className="option-button" style={{marginTop: '20px', textAlign: 'center'}} onClick={() => setFeedback(`Hint: ${activeChallenge.hint}`)}>
                    Need a hint?
                </button>
            </div>
        );
    }
    
    const allSolved = solved.length === ctfChallenges.length;
    const filteredChallenges = ctfChallenges.filter(c => c.category === selectedCategory);

    return (
        <div className="container">
            <h2>Capture The Flag</h2>
            <p className="game-description">Solve puzzles, find hidden clues, and capture the flags in this series of engaging cybersecurity challenges. Choose a category and click a challenge to begin.</p>
            {allSolved && (
                <div className="feedback feedback-correct">
                    <h3>Congratulations! You've captured all the flags!</h3>
                </div>
            )}

            <div className="ctf-category-tabs">
                {categories.map(category => (
                    <button 
                        key={category} 
                        className={`category-tab-button ${selectedCategory === category ? 'active' : ''}`}
                        onClick={() => setSelectedCategory(category)}
                    >
                        {category}
                    </button>
                ))}
            </div>

            <div className="ctf-challenge-grid">
                {filteredChallenges.map(challenge => {
                    const isSolved = solved.includes(challenge.id);
                    return (
                        <div key={challenge.id} className={`ctf-challenge-card ${isSolved ? 'solved' : ''}`} onClick={() => handleSelectChallenge(challenge)}
                         aria-label={`Challenge: ${challenge.title}. Status: ${isSolved ? 'Solved' : 'Unsolved'}`}>
                            <h4>{challenge.title}</h4>
                            <p>{challenge.difficulty}</p>
                        </div>
                    );
                })}
            </div>
             <button onClick={() => setSolved([])} className="play-again-button" style={{marginTop: '30px'}}>Reset Progress</button>
        </div>
    );
}

// 4. PENETRATION TESTING SIMULATOR
function PenetrationTestGame({ onGoHome }: { onGoHome: () => void }) {
    const [activeChallenge, setActiveChallenge] = useState<PentestChallenge | null>(null);
    const [history, setHistory] = useState<string[]>([]);
    const [currentStateKey, setCurrentStateKey] = useState<string | null>(null);
    const terminalRef = useRef<HTMLDivElement>(null);

    const categories = Array.from(new Set(pentestChallenges.map(c => c.category))).sort();
    const [selectedCategory, setSelectedCategory] = useState<string>(categories[0]);

    useEffect(() => {
        if (terminalRef.current) {
            terminalRef.current.scrollTop = terminalRef.current.scrollHeight;
        }
    }, [history]);
    
    useEffect(() => {
        if (activeChallenge) {
            const { initialState, states } = activeChallenge;
            setCurrentStateKey(initialState);
            setHistory([states[initialState].outputText]);
        }
    }, [activeChallenge]);


    const handleCommand = (command) => {
        if (!activeChallenge || !currentStateKey) return;
        const commandText = `$ ${command.text}`;
        const nextStateKey = command.nextState;
        const nextState = activeChallenge.states[nextStateKey];
        if (nextState) {
            setHistory(prev => [...prev, commandText, nextState.outputText]);
            setCurrentStateKey(nextStateKey);
        }
    };
    
    const restartCurrentChallenge = () => {
        if (!activeChallenge) return;
        const { initialState, states } = activeChallenge;
        setCurrentStateKey(initialState);
        setHistory([states[initialState].outputText]);
    };
    
    const goBackToSelection = () => {
        setActiveChallenge(null);
        setHistory([]);
        setCurrentStateKey(null);
    }

    if (!activeChallenge) {
        const filteredChallenges = pentestChallenges.filter(c => c.category === selectedCategory);
        return (
            <div className="container welcome-screen">
                <h2>Penetration Test Simulator</h2>
                <p className="game-description">You're a penetration tester. Choose a category, select a target, and use your skills to find vulnerabilities and capture the flag.</p>
                
                <div className="pentest-category-tabs">
                    {categories.map(category => (
                        <button 
                            key={category} 
                            className={`category-tab-button ${selectedCategory === category ? 'active' : ''}`}
                            onClick={() => setSelectedCategory(category)}
                        >
                            {category}
                        </button>
                    ))}
                </div>
                
                <div className="pentest-selection-grid">
                    {filteredChallenges.map((challenge) => (
                         <div key={challenge.id} className="pentest-card">
                            <h3>{challenge.title}</h3>
                            <p className="pentest-objective">{challenge.objective}</p>
                            <button onClick={() => setActiveChallenge(challenge)} className="start-button">Start Scenario</button>
                        </div>
                    ))}
                </div>
            </div>
        );
    }
    
    const currentState = activeChallenge.states[currentStateKey!];

    return (
        <div className="container">
            <button onClick={goBackToSelection} className="back-button">{'< Back to Scenario List'}</button>
            <h2>{activeChallenge.title}</h2>
            <p className="game-description"><strong>Objective:</strong> {activeChallenge.objective}</p>
            <div className="terminal-container" ref={terminalRef}>
                {history.map((line, index) => (
                    <pre key={index} className="terminal-output" dangerouslySetInnerHTML={{__html: line}}></pre>
                ))}
                {currentState.availableCommands.length > 0 && <span className="terminal-prompt">{'>'}</span>}
            </div>
            <div className="command-container">
                {currentState.availableCommands.length > 0 ? (
                    currentState.availableCommands.map(cmd => (
                        <button key={cmd.text} onClick={() => handleCommand(cmd)} className="command-button" title={cmd.description}>
                            {cmd.text}
                        </button>
                    ))
                ) : (
                    <button onClick={restartCurrentChallenge} className="play-again-button">Run Again</button>
                )}
            </div>
        </div>
    );
}

// 5. INCIDENT RESPONSE CHALLENGE
function IncidentResponseGame({ onGoHome }: { onGoHome: () => void }) {
    const [gameState, setGameState] = useState<'welcome' | 'playing'>('welcome');
    const [activeChallenge, setActiveChallenge] = useState<IncidentResponseChallenge | null>(null);
    const [log, setLog] = useState<string[]>([]);
    const [currentStateKey, setCurrentStateKey] = useState<string | null>(null);
    const logRef = useRef<HTMLDivElement>(null);
    
    const categories = Array.from(new Set(incidentResponseChallenges.map(c => c.category)));
    const [selectedCategory, setSelectedCategory] = useState<string>(categories[0]);


    useEffect(() => {
        if (logRef.current) {
            logRef.current.scrollTop = logRef.current.scrollHeight;
        }
    }, [log]);
    
    const startChallenge = (challenge: IncidentResponseChallenge) => {
        setActiveChallenge(challenge);
        setLog([`ALERT: ${challenge.initialAlert}`]);
        setCurrentStateKey(challenge.initialState);
        setGameState('playing');
    };

    const handleAction = (action) => {
        if (!activeChallenge) return;
        const nextState = activeChallenge.states[action.nextState];
        if (nextState) {
            setLog(prev => [...prev, `ACTION: ${action.text}`, `INFO: ${action.result}`, ...nextState.log]);
            setCurrentStateKey(action.nextState);
        }
    };
    
    const goBackToSelection = () => {
        setGameState('welcome');
        setActiveChallenge(null);
        setLog([]);
        setCurrentStateKey(null);
    }

    if (gameState === 'welcome') {
        const filteredChallenges = incidentResponseChallenges.filter(c => c.category === selectedCategory);
        return (
            <div className="container welcome-screen">
                <h2>Incident Response Challenge</h2>
                <p className="game-description">A security incident has occurred. As a SOC analyst, it's your job to triage, investigate, and contain the threat. Choose a category and an incident to begin.</p>
                
                <div className="incident-category-tabs">
                    {categories.map(category => (
                        <button 
                            key={category} 
                            className={`category-tab-button ${selectedCategory === category ? 'active' : ''}`}
                            onClick={() => setSelectedCategory(category)}
                        >
                            {category}
                        </button>
                    ))}
                </div>

                <div className="incident-selection-grid">
                    {filteredChallenges.map((challenge) => (
                        <div key={challenge.id} className="incident-card" onClick={() => startChallenge(challenge)}>
                            <div className="incident-card-header">
                                <h4>{challenge.title}</h4>
                                <span className="incident-card-category">{challenge.category}</span>
                            </div>
                            <p className="incident-card-description">{challenge.initialAlert}</p>
                            <button className="start-button">Start Challenge</button>
                        </div>
                    ))}
                </div>
            </div>
        );
    }
    
    if (!activeChallenge || !currentStateKey) {
        return <div className="container"><p>Loading...</p></div>;
    }

    const currentState = activeChallenge.states[currentStateKey];
    
    return (
        <div className="container">
            <button onClick={goBackToSelection} className="back-button">{'< Back to Incident List'}</button>
            <h2>{activeChallenge.title}</h2>
            <div className="incident-container">
                <div className="log-panel" ref={logRef}>
                    {log.map((entry, index) => {
                        const type = entry.startsWith('ALERT:') ? 'alert' : entry.startsWith('ACTION:') ? 'action' : 'info';
                        return <p key={index} className={`log-entry log-${type}`}>{entry}</p>
                    })}
                </div>
                <div className="actions-panel">
                    <h3>Available Actions</h3>
                    {currentState.availableActions.length > 0 ? (
                        currentState.availableActions.map(action => (
                            <button key={action.text} onClick={() => handleAction(action)} className="action-button">
                                {action.text}
                            </button>
                        ))
                    ) : (
                         <button onClick={goBackToSelection} className="play-again-button">New Incident</button>
                    )}
                </div>
            </div>
        </div>
    )
}

// 6. THREAT MODELING ARCHITECT
interface ThreatState extends Threat {
    status: 'unidentified' | 'placed' | 'mitigated';
}

function ThreatModelingGame({ onGoHome }: { onGoHome: () => void }) {
    const [activeChallenge, setActiveChallenge] = useState<ThreatModelingChallenge | null>(null);
    const [threats, setThreats] = useState<ThreatState[]>([]);
    const [selectedThreatId, setSelectedThreatId] = useState<string | null>(null);
    const [feedback, setFeedback] = useState<{ message: string; isError: boolean } | null>(null);
    const [selectedCategory, setSelectedCategory] = useState<string>('Web & Mobile');

    const categories = Array.from(new Set(threatModelingChallenges.map(c => c.category)));

    const startChallenge = (challenge: ThreatModelingChallenge) => {
        setActiveChallenge(challenge);
        setThreats(
            shuffleArray(challenge.threats).map(t => ({ ...t, status: 'unidentified' }))
        );
        setFeedback(null);
        setSelectedThreatId(null);
    };
    
    const goBackToSelection = () => {
        setActiveChallenge(null);
    };

    const handleSelectThreat = (threat: ThreatState) => {
        if (threat.status === 'mitigated') return;
        setFeedback(null);
        setSelectedThreatId(threat.id);
    };

    const handleDiagramClick = (e: React.MouseEvent) => {
        const selectedThreat = threats.find(t => t.id === selectedThreatId);
        if (!selectedThreat || selectedThreat.status !== 'unidentified') return;

        const componentElement = (e.target as Element).closest('.component');
        if (componentElement) {
            const componentName = componentElement.getAttribute('data-component-name');
            if (componentName) {
                if (selectedThreat.correctComponent === componentName) {
                    setFeedback({ message: `Correctly placed! The ${componentName} is indeed vulnerable.`, isError: false });
                    setThreats(ts => ts.map(t => t.id === selectedThreatId ? { ...t, status: 'placed' } : t));
                } else {
                    setFeedback({ message: `Incorrect. The '${selectedThreat.type}' threat doesn't primarily target the ${componentName}. Try again.`, isError: true });
                    setSelectedThreatId(null); 
                }
            }
        }
    };
    
    const handleSelectMitigation = (threatId: string, mitigation: string) => {
        const threat = threats.find(t => t.id === threatId);
        if (!threat || threat.status !== 'placed') return;
        
        if (mitigation === threat.mitigation) {
            setFeedback({ message: 'Threat Mitigated! Excellent work, Architect.', isError: false });
            setThreats(ts => ts.map(t => t.id === threatId ? { ...t, status: 'mitigated' } : t));
            setSelectedThreatId(null);
        } else {
            setFeedback({ message: `Not quite. That mitigation isn't the best fit for this threat. Think about the root cause.`, isError: true });
        }
    }
    
    if (!activeChallenge) {
        const filteredChallenges = threatModelingChallenges.filter(c => c.category === selectedCategory);
        return (
             <div className="container welcome-screen">
                <h2>Threat Modeling Architect</h2>
                <p className="game-description">You are a security architect. Analyze the system diagrams, identify where threats could occur based on STRIDE, and choose the correct mitigation. Think before you build!</p>
                
                <div className="threat-category-tabs">
                    {categories.map(category => (
                        <button 
                            key={category} 
                            className={`category-tab-button ${selectedCategory === category ? 'active' : ''}`}
                            onClick={() => setSelectedCategory(category)}
                        >
                            {category}
                        </button>
                    ))}
                </div>

                <div className="threat-selection-grid">
                    {filteredChallenges.map((challenge) => (
                         <div key={challenge.id} className="threat-card" onClick={() => startChallenge(challenge)}>
                            <h4>{challenge.title}</h4>
                            <p>{challenge.systemDescription}</p>
                            <span className="start-button">Start Scenario</span>
                        </div>
                    ))}
                </div>
            </div>
        );
    }
    
    const selectedThreat = threats.find(t => t.id === selectedThreatId) || null;
    const mitigatedCount = threats.filter(t => t.status === 'mitigated').length;
    const totalThreats = threats.length;
    const allThreatsMitigated = mitigatedCount === totalThreats;

    const getInstructionText = () => {
        if (allThreatsMitigated) return "Congratulations! You've mitigated all threats.";
        if (selectedThreat) {
            if (selectedThreat.status === 'unidentified') return "Step 2/3: Click the vulnerable component in the diagram.";
            if (selectedThreat.status === 'placed') return "Step 3/3: Correct! Now, choose the best mitigation.";
        }
        return "Step 1/3: Select a threat from the list below to begin.";
    }

    return (
        <div className="container threat-modeling-game">
            <button onClick={goBackToSelection} className="back-button">{'< Back to Scenario List'}</button>
            <h2 style={{marginBottom: '0.5em'}}>{activeChallenge.title}</h2>
            
            <div className="progress-bar-container">
                <div className="progress-bar">
                    <div className="progress-bar-fill" style={{ width: `${(mitigatedCount / totalThreats) * 100}%`}}></div>
                </div>
                <span>{mitigatedCount} / {totalThreats} Mitigated</span>
            </div>

            <div className="threat-modeling-board">
                <div 
                    className={`system-diagram-panel ${selectedThreat?.status === 'unidentified' ? 'threat-selected' : ''}`} 
                    onClick={handleDiagramClick} 
                    dangerouslySetInnerHTML={{ __html: activeChallenge.diagram }}>
                </div>
                
                <div className="interaction-panel">
                    <div className="instructions-box">
                        <h3>{getInstructionText()}</h3>
                        {feedback && <p className={`feedback ${feedback.isError ? 'feedback-incorrect' : 'feedback-correct'}`} aria-live="polite">{feedback.message}</p>}
                    </div>

                    {selectedThreat && selectedThreat.status !== 'mitigated' && (
                        <div className="selected-threat-details">
                            <div className="threat-header">
                                <div className={`stride-icon ${selectedThreat.type.toLowerCase().split(' ')[0]}`}>{selectedThreat.type.charAt(0)}</div>
                                <h4>{selectedThreat.type} Threat</h4>
                            </div>
                            <p className="threat-description">{selectedThreat.description}</p>
                            
                            {selectedThreat.status === 'placed' && (
                                <div className="mitigation-options">
                                    <h5>Choose Mitigation:</h5>
                                    {shuffleArray([selectedThreat.mitigation, ...selectedThreat.distractors]).map(m => (
                                       <button key={m} className="option-button" onClick={() => handleSelectMitigation(selectedThreat.id, m)}>{m}</button>
                                    ))}
                                </div>
                            )}
                        </div>
                    )}
                    {allThreatsMitigated && <p className="feedback feedback-correct" style={{textAlign: 'center', fontSize: '1.5em', marginTop: '2em'}}>Scenario Complete!</p>}
                </div>
            </div>
            
            <div className="threats-selection-tray">
                 {threats.sort((a, b) => parseInt(a.id.substring(1)) - parseInt(b.id.substring(1))).map(threat => (
                    <div 
                        key={threat.id} 
                        className={`threat-tray-item status-${threat.status} ${selectedThreatId === threat.id ? 'selected' : ''}`} 
                        onClick={() => handleSelectThreat(threat)}
                        role="button"
                        aria-pressed={selectedThreatId === threat.id}
                        tabIndex={threat.status === 'mitigated' ? -1 : 0}
                        onKeyDown={(e) => e.key === 'Enter' && handleSelectThreat(threat)}
                    >
                        <span className="status-icon"></span>
                        <div className={`stride-icon ${threat.type.toLowerCase().split(' ')[0]}`}>{threat.type.charAt(0)}</div>
                        <span className="threat-tray-title">{threat.type}</span>
                    </div>
                ))}
            </div>
        </div>
    );
}


// --- LANDING PAGE & APP ROUTER ---
function LandingPage({ onNavigate }: { onNavigate: (view: AppView) => void }) {
    const [showGames, setShowGames] = useState(false);
    const gamesSectionRef = useRef<HTMLElement>(null);

    const handleChooseChallenge = () => {
        setShowGames(true);
        setTimeout(() => {
            gamesSectionRef.current?.scrollIntoView({ behavior: 'smooth' });
        }, 100);
    };
    
    const games: { view: AppView; title: string; description: string; icon: React.ReactNode; accentColor: string; }[] = [
        { 
            view: 'incident', 
            title: 'Incident Response', 
            description: 'An urgent alert hits the SOC. Triage the threat, analyze data, and contain the breach in this defensive simulation.', 
            accentColor: '#dc3545',
            icon: (
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                    <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path>
                    <line x1="12" y1="9" x2="12" y2="13"></line><line x1="12" y1="17" x2="12.01" y2="17"></line>
                </svg>
            )
        },
        { 
            view: 'pentest', 
            title: 'Pentest Simulator', 
            description: 'Think like a hacker. Use common tools to scan a target, find vulnerabilities, and escalate privileges to capture the flag.', 
            accentColor: '#00ff7f',
            icon: (
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                    <polyline points="4 17 10 11 4 5"></polyline><line x1="12" y1="19" x2="20" y2="19"></line>
                </svg>
            )
        },
         { 
            view: 'threat', 
            title: 'Threat Modeling Architect', 
            description: 'Analyze system designs, identify potential security flaws based on STRIDE, and choose the right mitigations before a single line of code is written.', 
            accentColor: '#8a2be2',
            icon: (
                 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                   <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="3" y1="9" x2="21" y2="9"></line><line x1="9" y1="21" x2="9" y2="9"></line>
                </svg>
            )
        },
        { 
            view: 'phishing', 
            title: 'Spot the Phish', 
            description: 'Your inbox is the front line. Distinguish convincing fakes from legitimate emails to protect your credentials.', 
            accentColor: '#ffc107',
            icon: (
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                   <path d="M21.5,12a9.5,9.5,0,1,1-9.5-9.5A9.5,9.5,0,0,1,21.5,12Z"></path>
                   <path d="M12,16v-4a2,2,0,0,1,2-2h0a2,2,0,0,0-2-2h0a2,2,0,0,0-2,2H10"></path><line x1="12" y1="2" x2="12" y2="6"></line>
                </svg>
            )
        },
        { 
            view: 'ctf', 
            title: 'Capture The Flag', 
            description: 'A classic test of skill. Solve puzzles across cryptography, web exploitation, and forensics to find hidden flags.', 
            accentColor: '#e100ff',
            icon: (
                 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                    <path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"></path><line x1="4" y1="22" x2="4" y2="15"></line>
                </svg>
            )
        },
        { 
            view: 'quiz', 
            title: 'Cyber Quiz', 
            description: 'Test your foundational cybersecurity knowledge with our classic multiple-choice quiz.', 
            accentColor: '#00bfff',
            icon: (
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                    <path d="M14 9a2 2 0 0 1-2 2H6l-4 4V4c0-1.1.9-2 2-2h8a2 2 0 0 1 2 2v5Z"></path>
                    <path d="M18 9h2a2 2 0 0 1 2 2v11l-4-4h-6a2 2 0 0 1-2-2v-1"></path>
                </svg>
            )
        }
    ];

    return (
        <>
            <section className="hero-section">
                <h1>Enter the <span>Cyber</span> Arena</h1>
                <p className="hero-tagline">
                    Reading about cybersecurity is one thing. Facing it is another. We've moved beyond passive learning and built an interactive training ground where you can test your skills against realistic threats. From identifying sophisticated phishing emails to simulating a full penetration test, these challenges are designed to forge elite cyber defenders. Your training starts now.
                </p>
                <button onClick={handleChooseChallenge} className="cta-button">Choose Your Challenge</button>
            </section>
            
            <section ref={gamesSectionRef} className={`game-grid-container ${showGames ? 'visible' : ''}`}>
                <h2>Available Challenges</h2>
                <div className="game-grid">
                    {games.map(game => (
                        <div key={game.view} className="game-card" style={{ '--card-accent-color': game.accentColor } as React.CSSProperties}>
                           <div className="game-card-icon">{game.icon}</div>
                            <h3>{game.title}</h3>
                            <p>{game.description}</p>
                            <button className="play-button" onClick={() => onNavigate(game.view)}>Launch Scenario</button>
                        </div>
                    ))}
                </div>
            </section>
        </>
    );
}

function App() {
  const getViewFromPath = (path: string): AppView => {
    if (path === '/') return 'landing';
    const view = path.substring(1) as AppView; // remove leading '/'
    const validViews: AppView[] = ['quiz', 'phishing', 'ctf', 'pentest', 'incident', 'threat'];
    if (validViews.includes(view)) {
      return view;
    }
    return 'landing';
  };
  
  const [view, setView] = useState<AppView>(() => getViewFromPath(window.location.pathname));

  const navigate = (newView: AppView) => {
    const path = newView === 'landing' ? '/' : `/${newView}`;
    if (window.location.pathname !== path) {
        window.history.pushState({ view: newView }, '', path);
    }
    setView(newView);
    window.scrollTo(0, 0); // Scroll to top on navigation
  };

  useEffect(() => {
    const onPopState = (event: PopStateEvent) => {
      setView(getViewFromPath(window.location.pathname));
    };
    window.addEventListener('popstate', onPopState);
    return () => {
      window.removeEventListener('popstate', onPopState);
    };
  }, []);
  
  useEffect(() => {
    let title = 'Cyber Games Platform | Interactive Cybersecurity Training';
    switch(view) {
        case 'quiz': title = 'Cyber Quiz | Cyber Games Platform'; break;
        case 'phishing': title = 'Spot the Phish | Cyber Games Platform'; break;
        case 'ctf': title = 'Capture The Flag | Cyber Games Platform'; break;
        case 'pentest': title = 'Pentest Simulator | Cyber Games Platform'; break;
        case 'incident': title = 'Incident Response | Cyber Games Platform'; break;
        case 'threat': title = 'Threat Modeling | Cyber Games Platform'; break;
        case 'landing':
        default:
          title = 'Cyber Games Platform | Interactive Cybersecurity Training';
    }
    document.title = title;
  }, [view]);

  const renderView = () => {
    switch (view) {
      case 'quiz':
        return <QuizGame onGoHome={() => navigate('landing')} />;
      case 'phishing':
        return <PhishingGame onGoHome={() => navigate('landing')} />;
      case 'ctf':
        return <CtfGame onGoHome={() => navigate('landing')} />;
      case 'pentest':
        return <PenetrationTestGame onGoHome={() => navigate('landing')} />;
      case 'incident':
        return <IncidentResponseGame onGoHome={() => navigate('landing')} />;
      case 'threat':
        return <ThreatModelingGame onGoHome={() => navigate('landing')} />;
      case 'landing':
      default:
        return <LandingPage onNavigate={navigate} />;
    }
  };

  return (
    <>
      <header id="app-header" style={{ display: view === 'landing' ? 'none' : 'flex' }}>
          <button onClick={() => navigate('landing')} className="home-icon-button" aria-label="Go to Home">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
              <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8h5z" />
              <path d="M0 0h24v24H0z" fill="none" />
            </svg>
          </button>
        <h1>Cyber Games</h1>
      </header>
      {renderView()}
    </>
  );
}

const rootElement = document.getElementById('root');
if (rootElement) {
    const root = ReactDOM.createRoot(rootElement);
    root.render(<App />);
} else {
    console.error('Root element not found for React rendering.');
}