#!/usr/bin/env python3
"""
ExamCraft: Demo with Visible Question Generation

This version shows the actual questions being generated by the teacher AI,
perfect for demonstrating the adaptive teaching capabilities!
"""

import json
import os
import random
from typing import Any, Dict, Tuple


class VisibleQuestionDemo:
    """
    ExamCraft demo that shows the actual questions being generated.
    Great for video demonstrations!
    """

    def __init__(self, profile_path: str = "example_profile.json"):
        # Load student profile
        if os.path.exists(profile_path):
            with open(profile_path, "r") as file:
                self.profile = json.load(file)
        else:
            self.profile = self._create_default_profile()

        # Initialize student metrics
        self.reset_student()

        # Question templates for realistic generation
        self.question_templates = {
            "vectors": {
                "easy": [
                    {
                        "question": "What is the result when you add vectors (2,3) and (1,4)?",
                        "options": {
                            "A": "(3,7)",
                            "B": "(2,12)",
                            "C": "(1,1)",
                            "D": "(3,1)",
                        },
                        "correct": "A",
                        "explanation": "Vector addition is component-wise: (2+1, 3+4) = (3,7)",
                    },
                    {
                        "question": "Which operation can you perform on vectors?",
                        "options": {
                            "A": "Addition",
                            "B": "Scalar multiplication",
                            "C": "Dot product",
                            "D": "All of the above",
                        },
                        "correct": "D",
                        "explanation": "Vectors support addition, scalar multiplication, and dot product operations",
                    },
                ],
                "medium": [
                    {
                        "question": "Calculate the dot product of vectors (3,4) and (1,2):",
                        "options": {"A": "11", "B": "7", "C": "5", "D": "10"},
                        "correct": "A",
                        "explanation": "Dot product: (3×1) + (4×2) = 3 + 8 = 11",
                    },
                    {
                        "question": "What is the magnitude of vector (3,4)?",
                        "options": {"A": "5", "B": "7", "C": "3.5", "D": "4.5"},
                        "correct": "A",
                        "explanation": "Magnitude = √(3² + 4²) = √(9 + 16) = √25 = 5",
                    },
                ],
                "hard": [
                    {
                        "question": "If vectors u and v are orthogonal, what is u·v?",
                        "options": {"A": "1", "B": "0", "C": "-1", "D": "Undefined"},
                        "correct": "B",
                        "explanation": "Orthogonal vectors have dot product = 0 by definition",
                    }
                ],
            },
            "matrices": {
                "easy": [
                    {
                        "question": "What is the result of [1 2] + [3 4]?",
                        "options": {
                            "A": "[4 6]",
                            "B": "[3 8]",
                            "C": "[1 2]",
                            "D": "[2 4]",
                        },
                        "correct": "A",
                        "explanation": "Matrix addition: [1+3, 2+4] = [4, 6]",
                    }
                ],
                "medium": [
                    {
                        "question": "What is the determinant of [[2,1],[3,4]]?",
                        "options": {"A": "5", "B": "8", "C": "11", "D": "7"},
                        "correct": "A",
                        "explanation": "det = (2×4) - (1×3) = 8 - 3 = 5",
                    }
                ],
                "hard": [
                    {
                        "question": "A matrix is invertible if and only if:",
                        "options": {
                            "A": "It's square",
                            "B": "Det ≠ 0",
                            "C": "All entries > 0",
                            "D": "It's symmetric",
                        },
                        "correct": "B",
                        "explanation": "A matrix is invertible iff its determinant is non-zero",
                    }
                ],
            },
            "linear_systems": {
                "easy": [
                    {
                        "question": "A system with no solutions is called:",
                        "options": {
                            "A": "Consistent",
                            "B": "Inconsistent",
                            "C": "Homogeneous",
                            "D": "Independent",
                        },
                        "correct": "B",
                        "explanation": "Inconsistent systems have no solutions",
                    }
                ],
                "medium": [
                    {
                        "question": "In Gaussian elimination, what creates a pivot?",
                        "options": {
                            "A": "Leading 1",
                            "B": "Zero entry",
                            "C": "Negative number",
                            "D": "Largest element",
                        },
                        "correct": "A",
                        "explanation": "Pivots are the leading 1's in row echelon form",
                    }
                ],
                "hard": [
                    {
                        "question": (
                            "For what values of k does the system have infinitely many solutions?\n"
                            "2x + 3y = 6\n4x + 6y = k"
                        ),
                        "options": {
                            "A": "k = 6",
                            "B": "k = 12",
                            "C": "k = 0",
                            "D": "k = 3",
                        },
                        "correct": "B",
                        "explanation": "The second equation must be a multiple of the first: k = 2×6 = 12",
                    }
                ],
            },
            "eigenvalues_eigenvectors": {
                "easy": [
                    {
                        "question": "An eigenvector of matrix A satisfies:",
                        "options": {
                            "A": "Av = λv",
                            "B": "Av = v",
                            "C": "Av = 0",
                            "D": "Av = I",
                        },
                        "correct": "A",
                        "explanation": "By definition: Av = λv where λ is the eigenvalue",
                    }
                ],
                "medium": [
                    {
                        "question": "To find eigenvalues, we solve:",
                        "options": {
                            "A": "det(A) = 0",
                            "B": "det(A - λI) = 0",
                            "C": "Av = 0",
                            "D": "tr(A) = λ",
                        },
                        "correct": "B",
                        "explanation": "Eigenvalues satisfy the characteristic equation det(A - λI) = 0",
                    }
                ],
                "hard": [
                    {
                        "question": "The sum of eigenvalues equals:",
                        "options": {
                            "A": "Determinant",
                            "B": "Trace",
                            "C": "Rank",
                            "D": "Nullity",
                        },
                        "correct": "B",
                        "explanation": "The sum of eigenvalues equals the trace of the matrix",
                    }
                ],
            },
        }

        # Track teaching session
        self.question_count = 0
        self.session_history = []

    def _create_default_profile(self) -> Dict[str, Any]:
        """Create default student profile."""
        return {
            "student_id": "adaptive_learner_001",
            "target_grade": "11th grade",
            "learning_goal": "Master linear algebra concepts",
            "topics": [
                {"name": "vectors", "proficiency": 0.45},
                {"name": "matrices", "proficiency": 0.30},
                {"name": "linear_systems", "proficiency": 0.25},
                {"name": "eigenvalues_eigenvectors", "proficiency": 0.20},
            ],
        }

    def reset_student(self):
        """Reset student to initial proficiency levels."""
        self.student_metrics = {}
        for topic in self.profile["topics"]:
            self.student_metrics[topic["name"]] = topic["proficiency"]

        self.question_count = 0
        self.session_history = []

    def generate_question(self, topic: str, difficulty: str) -> Dict[str, Any]:
        """Generate a specific question for the topic and difficulty."""
        # Get question templates for this topic/difficulty
        topic_questions = self.question_templates.get(topic, {})
        difficulty_questions = topic_questions.get(difficulty, [])

        if difficulty_questions:
            # Select a random question from available templates
            question_data = random.choice(difficulty_questions)

            # Add metadata
            question_data.update(
                {
                    "topic": topic,
                    "difficulty": difficulty,
                    "generated_by": "ExamCraft Teacher AI",
                }
            )

            return question_data
        else:
            # Fallback question if no template available
            return {
                "topic": topic,
                "difficulty": difficulty,
                "question": f"Sample {difficulty} question about {topic}",
                "options": {
                    "A": "Option A",
                    "B": "Option B",
                    "C": "Option C",
                    "D": "Option D",
                },
                "correct": "A",
                "explanation": f"This demonstrates {difficulty} level understanding of {topic}",
                "generated_by": "ExamCraft Teacher AI (fallback)",
            }

    def simulate_student_answer(
        self, question_data: Dict[str, Any]
    ) -> Tuple[str, bool]:
        """Simulate student answering the question."""
        topic = question_data["topic"]
        difficulty = question_data["difficulty"]
        correct_answer = question_data["correct"]

        # Get student's current proficiency
        proficiency = self.student_metrics[topic]

        # Adjust success probability based on difficulty
        difficulty_modifiers = {"easy": 0.25, "medium": 0.0, "hard": -0.25}
        modifier = difficulty_modifiers.get(difficulty, 0.0)

        # Calculate success probability
        success_prob = max(0.15, min(0.90, proficiency + modifier))

        # Determine if answer is correct
        is_correct = random.random() < success_prob

        if is_correct:
            student_answer = correct_answer
        else:
            # Choose random incorrect answer
            options = list(question_data["options"].keys())
            options.remove(correct_answer)
            student_answer = random.choice(options)

        return student_answer, is_correct

    def update_student_learning(self, topic: str, is_correct: bool, difficulty: str):
        """Update student's proficiency based on learning."""
        current_prof = self.student_metrics[topic]

        # Learning rate based on correctness and difficulty
        if is_correct:
            base_improvement = 0.05
        else:
            # Student learns from mistakes with good explanations
            base_improvement = 0.03

        # Difficulty affects learning
        difficulty_multipliers = {"easy": 0.7, "medium": 1.0, "hard": 1.3}
        multiplier = difficulty_multipliers.get(difficulty, 1.0)

        improvement = base_improvement * multiplier

        # Diminishing returns as proficiency increases
        diminishing_factor = (1.0 - current_prof) * 0.8 + 0.2
        improvement *= diminishing_factor

        # Update proficiency
        new_prof = min(1.0, current_prof + improvement)
        self.student_metrics[topic] = new_prof

    def get_weakest_topic(self) -> str:
        """Find the topic where student is struggling most."""
        return min(self.student_metrics.items(), key=lambda x: x[1])[0]

    def select_difficulty(self, topic: str) -> str:
        """Select appropriate difficulty based on student proficiency."""
        proficiency = self.student_metrics[topic]

        if proficiency < 0.4:
            return "easy"
        elif proficiency < 0.7:
            return "medium"
        else:
            return "hard"

    def run_visual_demo(self, num_questions: int = 5):
        """Run a demo showing actual question generation."""
        print("🎓 ExamCraft: Visual Question Generation Demo")
        print("=" * 60)

        # Show initial state
        print("\n📊 Initial Student Proficiency:")
        for topic, prof in self.student_metrics.items():
            print(f"  {topic.replace('_', ' ').title()}: {prof:.1%}")

        print(f"\n🎯 Teacher AI will generate {num_questions} adaptive questions")
        print("🧠 Watch how it targets weak areas and adapts difficulty!\n")

        for i in range(num_questions):
            print(f"\n{'='*20} Question {i+1} {'='*20}")

            # Teacher AI analyzes student and selects topic/difficulty
            target_topic = self.get_weakest_topic()
            difficulty = self.select_difficulty(target_topic)
            current_prof = self.student_metrics[target_topic]

            print("🤖 Teacher AI Analysis:")
            print(
                f"   Weakest topic: {target_topic.replace('_', ' ').title()} ({current_prof:.1%})"
            )
            print(f"   Selected difficulty: {difficulty.upper()}")

            # Generate the actual question
            print("\n📝 Generated Question:")
            question_data = self.generate_question(target_topic, difficulty)

            print(f"   Topic: {question_data['topic'].replace('_', ' ').title()}")
            print(f"   Difficulty: {question_data['difficulty'].upper()}")
            print(f"   Question: {question_data['question']}")
            print("   Options:")
            for option, text in question_data["options"].items():
                print(f"      {option}) {text}")

            # Student answers
            student_answer, is_correct = self.simulate_student_answer(question_data)
            correct_answer = question_data["correct"]

            print("\n👨‍🎓 Student Response:")
            answered_option = question_data["options"][student_answer]
            print(f"   Answered: {student_answer}) {answered_option}")
            option_text = question_data["options"][correct_answer]
            print(f"   Correct answer: {correct_answer}) {option_text}")

            result_icon = "✅ CORRECT" if is_correct else "❌ INCORRECT"
            print(f"   Result: {result_icon}")

            # Show explanation
            print("\n💡 Teacher's Explanation:")
            print(f"   {question_data['explanation']}")

            # Update student learning
            old_prof = current_prof
            self.update_student_learning(target_topic, is_correct, difficulty)
            new_prof = self.student_metrics[target_topic]

            print("\n📈 Learning Progress:")
            topic_title = target_topic.replace("_", " ").title()
            improvement = new_prof - old_prof
            print(
                f"   {topic_title}: {old_prof:.1%} → {new_prof:.1%} (+{improvement:.1%})"
            )

            # Track this interaction
            self.question_count += 1
            self.session_history.append(
                {
                    "question_num": i + 1,
                    "topic": target_topic,
                    "difficulty": difficulty,
                    "question": question_data,
                    "student_answer": student_answer,
                    "is_correct": is_correct,
                    "proficiency_before": old_prof,
                    "proficiency_after": new_prof,
                }
            )

        # Final summary
        print(f"\n{'='*60}")
        print("📋 TEACHING SESSION SUMMARY")
        print(f"✨ Questions generated: {self.question_count}")

        print("\n🏆 Final Student Proficiency:")
        for topic, prof in self.student_metrics.items():
            original_prof = next(
                t["proficiency"] for t in self.profile["topics"] if t["name"] == topic
            )
            improvement = prof - original_prof
            print(
                f"  {topic.replace('_', ' ').title()}: {prof:.1%} (+{improvement:.1%})"
            )

        print("\n🎯 Adaptive Teaching Demonstrated:")
        topics_targeted = set(item["topic"] for item in self.session_history)
        print(f"  - Targeted {len(topics_targeted)} different topics")
        print("  - Difficulty adapted based on performance")
        print("  - Each question included detailed explanations")

        return self.session_history


def main():
    """Run the visual question generation demo."""
    demo = VisibleQuestionDemo()

    print("🎬 ExamCraft: Question Generation Demo")
    print("Perfect for recording your hackathon video!\n")

    num_questions = 5
    try:
        user_input = input(
            f"How many questions to generate? (default {num_questions}): "
        ).strip()
        if user_input:
            num_questions = int(user_input)
    except ValueError:
        pass

    # Run the demo
    demo.run_visual_demo(num_questions)

    print("\n🎥 This demo shows:")
    print("✓ Teacher AI analyzing student weaknesses")
    print("✓ Adaptive question generation with real content")
    print("✓ Student simulation and learning progression")
    print("✓ Detailed explanations and feedback")
    print("\nPerfect for your 1-minute hackathon demo video! 🚀")


if __name__ == "__main__":
    main()
