"""Universal quiz system supporting multiple question types."""

from __future__ import annotations

import json
import random
from dataclasses import dataclass, field
from enum import Enum
from functools import cached_property
from pathlib import Path
from typing import Any


class QuestionType(Enum):
    """Supported question types."""

    MULTIPLE_CHOICE = "multiple_choice"
    FILL_BLANK = "fill_blank"
    TRUE_FALSE = "true_false"
    ESSAY = "essay"


@dataclass
class Question:
    """Base question data structure."""

    question_id: str
    question_type: QuestionType
    question_text: str
    points: float = 1.0

    def check_answer(self, answer: Any) -> tuple[bool, str]:
        """Check if answer is correct. Returns (is_correct, explanation)."""
        raise NotImplementedError

    def to_dict(self) -> dict[str, Any]:
        """Convert question to dictionary format."""
        return {
            "question_id": self.question_id,
            "question_type": self.question_type.value,
            "question_text": self.question_text,
            "points": self.points,
        }

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> Question:
        """Create question instance from dictionary."""
        qtype = QuestionType(data["question_type"])

        if qtype == QuestionType.MULTIPLE_CHOICE:
            return MultipleChoiceQuestion.from_dict(data)
        if qtype == QuestionType.FILL_BLANK:
            return FillBlankQuestion.from_dict(data)
        if qtype == QuestionType.TRUE_FALSE:
            return TrueFalseQuestion.from_dict(data)
        if qtype == QuestionType.ESSAY:
            return EssayQuestion.from_dict(data)
        raise ValueError(f"Unknown question type: {qtype}")


@dataclass
class MultipleChoiceQuestion(Question):
    """Multiple choice question with single or multiple answers."""

    options: list[str] = field(default_factory=list)
    correct_answer: list[int] | int = field(default_factory=list)  # Index/indices of correct options
    allow_multiple: bool = False

    def check_answer(self, answer: int | list[int]) -> tuple[bool, str]:
        """Check if selected option(s) match correct answer."""
        if isinstance(answer, int):
            answer = [answer]

        if not isinstance(self.correct_answer, list):
            correct = [self.correct_answer]
        else:
            correct = self.correct_answer

        is_correct = sorted(answer) == sorted(correct)
        explanation = self._generate_explanation(answer, correct)
        return is_correct, explanation

    def _generate_explanation(self, selected: list[int], correct: list[int]) -> str:
        """Generate explanation for the answer."""
        if not self.allow_multiple:
            correct_text = self.options[correct[0]]
            if sorted(selected) == sorted(correct):
                return f"Correct! {correct_text} is the right answer."
            return f"Incorrect. The correct answer is: {correct_text}"

        correct_texts = [self.options[i] for i in correct]
        if sorted(selected) == sorted(correct):
            return f"Correct! {', '.join(correct_texts)} are the right answers."
        return f"Incorrect. The correct answers are: {', '.join(correct_texts)}"

    def to_dict(self) -> dict[str, Any]:
        """Convert to dictionary format."""
        base = super().to_dict()
        base.update(
            {
                "options": self.options,
                "correct_answer": self.correct_answer,
                "allow_multiple": self.allow_multiple,
            }
        )
        return base

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> MultipleChoiceQuestion:
        """Create instance from dictionary."""
        return cls(
            question_id=data["question_id"],
            question_type=QuestionType.MULTIPLE_CHOICE,
            question_text=data["question_text"],
            points=data.get("points", 1.0),
            options=data["options"],
            correct_answer=data["correct_answer"],
            allow_multiple=data.get("allow_multiple", False),
        )


@dataclass
class FillBlankQuestion(Question):
    """Fill in the blank question."""

    correct_answers: list[str] = field(default_factory=list)  # Multiple acceptable answers
    case_sensitive: bool = False

    def check_answer(self, answer: str) -> tuple[bool, str]:
        """Check if answer matches any correct option."""
        if not self.case_sensitive:
            answer = answer.strip().lower()
            valid_answers = [a.strip().lower() for a in self.correct_answers]
        else:
            answer = answer.strip()
            valid_answers = [a.strip() for a in self.correct_answers]

        is_correct = answer in valid_answers
        if is_correct:
            return True, f"Correct! '{answer}' is the right answer."
        return False, f"Incorrect. Valid answers are: {', '.join(self.correct_answers)}"

    def to_dict(self) -> dict[str, Any]:
        """Convert to dictionary format."""
        base = super().to_dict()
        base.update(
            {
                "correct_answers": self.correct_answers,
                "case_sensitive": self.case_sensitive,
            }
        )
        return base

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> FillBlankQuestion:
        """Create instance from dictionary."""
        return cls(
            question_id=data["question_id"],
            question_type=QuestionType.FILL_BLANK,
            question_text=data["question_text"],
            points=data.get("points", 1.0),
            correct_answers=data["correct_answers"],
            case_sensitive=data.get("case_sensitive", False),
        )


@dataclass
class TrueFalseQuestion(Question):
    """True/False question."""

    correct_answer: bool = True

    def check_answer(self, answer: bool | str) -> tuple[bool, str]:
        """Check if answer matches correct value."""
        if isinstance(answer, str):
            answer_lower = answer.strip().lower()
            if answer_lower in ("true", "t", "yes", "y"):
                answer = True
            elif answer_lower in ("false", "f", "no", "n"):
                answer = False
            else:
                return False, "Invalid input. Please enter True or False."

        is_correct = answer == self.correct_answer
        correct_text = "True" if self.correct_answer else "False"
        if is_correct:
            return True, f"Correct! The statement is {correct_text}."
        return False, f"Incorrect. The statement is {correct_text}."

    def to_dict(self) -> dict[str, Any]:
        """Convert to dictionary format."""
        base = super().to_dict()
        base.update({"correct_answer": self.correct_answer})
        return base

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> TrueFalseQuestion:
        """Create instance from dictionary."""
        return cls(
            question_id=data["question_id"],
            question_type=QuestionType.TRUE_FALSE,
            question_text=data["question_text"],
            points=data.get("points", 1.0),
            correct_answer=data["correct_answer"],
        )


@dataclass
class EssayQuestion(Question):
    """Essay question requiring detailed answer."""

    model_answer: str = ""
    keywords: list[str] = field(default_factory=list)  # Optional keywords for validation

    def check_answer(self, answer: str) -> tuple[bool, str]:
        """Check if answer contains key points (soft validation)."""
        answer_lower = answer.lower()

        if self.keywords:
            matched_keywords = [kw for kw in self.keywords if kw.lower() in answer_lower]
            keyword_count = len(self.keywords)
            matched_count = len(matched_keywords)

            if matched_count >= keyword_count * 0.5:  # At least 50% of keywords
                return (
                    True,
                    f"Good answer! You covered {matched_count}/{keyword_count} "
                    f"key points: {', '.join(matched_keywords)}",
                )
            return (
                False,
                f"Your answer is incomplete. Consider including: {', '.join(self.keywords)}",
            )

        return True, "Answer recorded. Review model answer for comparison."

    def to_dict(self) -> dict[str, Any]:
        """Convert to dictionary format."""
        base = super().to_dict()
        base.update(
            {
                "model_answer": self.model_answer,
                "keywords": self.keywords,
            }
        )
        return base

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> EssayQuestion:
        """Create instance from dictionary."""
        return cls(
            question_id=data["question_id"],
            question_type=QuestionType.ESSAY,
            question_text=data["question_text"],
            points=data.get("points", 1.0),
            model_answer=data.get("model_answer", ""),
            keywords=data.get("keywords", []),
        )


@dataclass
class QuizResult:
    """Result of answering a question."""

    question: Question
    user_answer: Any
    is_correct: bool
    explanation: str

    def to_dict(self) -> dict[str, Any]:
        """Convert result to dictionary."""
        return {
            "question": self.question.to_dict(),
            "user_answer": self.user_answer,
            "is_correct": self.is_correct,
            "explanation": self.explanation,
        }


@dataclass
class QuizSession:
    """Manage a quiz session with multiple questions."""

    questions: list[Question] = field(default_factory=list)
    random_order: bool = False
    wrong_answer_file: str = "wrong_answers.json"
    results: list[QuizResult] = field(default_factory=list)
    _current_index: int = 0
    _shuffled_indices: list[int] = field(default_factory=list)
    # Flag to control adaptive behavior (default False for regular QuizSession)
    adaptive_mode: bool = False

    @cached_property
    def total_questions(self) -> int:
        """Get total number of questions."""
        return len(self.questions)

    @cached_property
    def correct_count(self) -> int:
        """Get number of correct answers."""
        return sum(1 for r in self.results if r.is_correct)

    @cached_property
    def wrong_count(self) -> int:
        """Get number of wrong answers."""
        return sum(1 for r in self.results if not r.is_correct)

    @cached_property
    def total_points(self) -> float:
        """Get total possible points."""
        return sum(q.points for q in self.questions)

    @cached_property
    def earned_points(self) -> float:
        """Get points earned."""
        return sum(r.question.points for r in self.results if r.is_correct)

    @cached_property
    def accuracy(self) -> float:
        """Calculate accuracy percentage."""
        if len(self.results) == 0:
            return 0.0
        return (self.correct_count / len(self.results)) * 100

    def load_from_json(self, json_file: str | Path) -> None:
        """Load questions from JSON file."""
        with open(json_file, encoding="utf-8") as f:
            data = json.load(f)

        self.questions = [Question.from_dict(q) for q in data.get("questions", [])]
        self._initialize_order()

    def _initialize_order(self) -> None:
        """Initialize question order based on randomization settings.

        Creates shuffled indices if random_order is enabled, otherwise uses
        sequential ordering. Called when loading questions or resetting session.
        """
        if self.random_order:
            self._shuffled_indices = list(range(self.total_questions))
            random.shuffle(self._shuffled_indices)
        else:
            self._shuffled_indices = list(range(self.total_questions))

    def get_current_question(self) -> Question | None:
        """Get the current question based on session progress.

        Returns the question at the current index according to the shuffled
        or sequential order. Returns None if all questions have been answered.

        Returns
        -------
            Current Question object or None if quiz is finished
        """
        if self._current_index >= len(self._shuffled_indices):
            return None
        idx = self._shuffled_indices[self._current_index]
        return self.questions[idx]

    def submit_answer(self, answer: Any) -> QuizResult | None:
        """Submit an answer for the current question and advance to next.

        Evaluates the answer against the current question, records the result,
        and moves to the next question in the sequence.

        Args:
            answer: User's answer to evaluate

        Returns
        -------
            QuizResult containing evaluation results, or None if no current question
        """
        question = self.get_current_question()
        if question is None:
            return None

        is_correct, explanation = question.check_answer(answer)
        result = QuizResult(
            question=question,
            user_answer=answer,
            is_correct=is_correct,
            explanation=explanation,
        )
        self.results.append(result)
        self._current_index += 1
        return result

    def is_finished(self) -> bool:
        """Check if quiz is finished."""
        return self._current_index >= len(self._shuffled_indices)

    def get_wrong_answers(self) -> list[QuizResult]:
        """Get all wrong answers."""
        return [r for r in self.results if not r.is_correct]

    def save_wrong_answers(self, file_path: str | Path | None = None) -> None:
        """Save wrong answers to JSON file."""
        wrong_answers = self.get_wrong_answers()
        if not wrong_answers:
            return

        output_path = Path(file_path) if file_path else Path(self.wrong_answer_file)
        data = {"wrong_answers": [r.to_dict() for r in wrong_answers]}
        with open(output_path, "w", encoding="utf-8") as f:
            json.dump(data, f, indent=2, ensure_ascii=False)

    def get_summary(self) -> dict[str, Any]:
        """Get quiz session summary."""
        return {
            "total_questions": self.total_questions,
            "answered": len(self.results),
            "correct": self.correct_count,
            "wrong": self.wrong_count,
            "total_points": self.total_points,
            "earned_points": self.earned_points,
            "accuracy": self.accuracy,
            "is_finished": self.is_finished(),
        }

    def reset(self, random_order: bool | None = None) -> None:
        """Reset quiz session."""
        self._current_index = 0
        self.results = []
        if random_order is not None:
            self.random_order = random_order
        self._initialize_order()


def create_sample_quiz_data(output_file: str | Path) -> None:
    """Create sample quiz data file with all question types."""
    questions = [
        {
            "question_id": "mc1",
            "question_type": "multiple_choice",
            "question_text": "What is the capital of France?",
            "options": ["London", "Paris", "Berlin", "Rome"],
            "correct_answer": 1,
            "allow_multiple": False,
            "points": 1.0,
        },
        {
            "question_id": "mc2",
            "question_type": "multiple_choice",
            "question_text": "Which of the following are programming languages? (Select all that apply)",
            "options": ["Python", "HTML", "Java", "CSS", "JavaScript"],
            "correct_answer": [0, 2, 4],
            "allow_multiple": True,
            "points": 2.0,
        },
        {
            "question_id": "fb1",
            "question_type": "fill_blank",
            "question_text": "The planet closest to the Sun is _____.",
            "correct_answers": ["Mercury"],
            "case_sensitive": False,
            "points": 1.0,
        },
        {
            "question_id": "fb2",
            "question_type": "fill_blank",
            "question_text": "The largest ocean on Earth is the _____ Ocean.",
            "correct_answers": ["Pacific", "pacific", "PACIFIC"],
            "case_sensitive": False,
            "points": 1.0,
        },
        {
            "question_id": "tf1",
            "question_type": "true_false",
            "question_text": "Python is a compiled language.",
            "correct_answer": False,
            "points": 1.0,
        },
        {
            "question_id": "tf2",
            "question_type": "true_false",
            "question_text": "The Earth revolves around the Sun.",
            "correct_answer": True,
            "points": 1.0,
        },
        {
            "question_id": "es1",
            "question_type": "essay",
            "question_text": "Explain the concept of object-oriented programming.",
            "model_answer": (
                "Object-oriented programming (OOP) is a programming paradigm "
                "based on the concept of objects, which can contain data and code. "
                "The four main principles are encapsulation, abstraction, inheritance, and polymorphism."
            ),
            "keywords": [
                "objects",
                "classes",
                "inheritance",
                "encapsulation",
                "polymorphism",
                "abstraction",
            ],
            "points": 5.0,
        },
    ]

    data = {"title": "General Knowledge Quiz", "questions": questions}
    output_path = Path(output_file)
    output_path.parent.mkdir(parents=True, exist_ok=True)
    with open(output_path, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=2, ensure_ascii=False)


def main():
    """Run entry point for the command-line interface.

    Quizbase utility tool

    Examples
    --------
      quizbase [options] <arguments>
    """
    import argparse

    parser = argparse.ArgumentParser(description="Universal quiz system")
    parser.add_argument("--create-sample", action="store_true", help="Create sample quiz data file")
    parser.add_argument("--file", type=str, help="Quiz JSON file to load")
    parser.add_argument("--random", action="store_true", help="Shuffle questions")
    parser.add_argument(
        "--adaptive",
        action="store_true",
        help="Use adaptive question selection based on performance",
    )
    parser.add_argument(
        "--history-file",
        type=str,
        help="File to load/save user performance history",
        default="user_performance.json",
    )
    parser.add_argument("--wrong", type=str, help="Save wrong answers to file")
    args = parser.parse_args()

    if args.create_sample:
        sample_file = Path("sample_quiz.json")
        create_sample_quiz_data(sample_file)
        print(f"Sample quiz data created: {sample_file}")
        return

    if args.file:
        # Use adaptive session if adaptive flag is set
        if args.adaptive:
            session = AdaptiveQuizSession(random_order=args.random)
            session.history_file = args.history_file
            session.load_performance_history()
        else:
            session = QuizSession(random_order=args.random)

        if args.wrong:
            session.wrong_answer_file = args.wrong
        session.load_from_json(args.file)

        print(
            f"\n=== Quiz Started ({'Adaptive' if args.adaptive else 'Random' if args.random else 'Sequential'} "
            f"Order) ==="
        )
        print(f"Total Questions: {session.total_questions}\n")

        while not session.is_finished():
            question = session.get_current_question()
            if question is None:
                break

            print(f"\nQuestion {len(session.results) + 1}/{session.total_questions}")
            print(f"[{question.question_type.value}] {question.question_text}")
            print(f"Points: {question.points}")

            if isinstance(question, MultipleChoiceQuestion):
                for i, option in enumerate(question.options):
                    print(f"  {i}. {option}")

            answer = input("\nYour answer: ")

            try:
                if isinstance(question, MultipleChoiceQuestion):
                    if question.allow_multiple:
                        answer = [int(x.strip()) for x in answer.split(",")]
                    else:
                        answer = int(answer)
                elif isinstance(question, TrueFalseQuestion):
                    answer = answer.strip().lower() in ("true", "t", "yes", "y")
                elif isinstance(question, EssayQuestion):
                    answer = answer
                else:
                    answer = answer

                result = session.submit_answer(answer)
                if result:
                    print(f"\n{'✓' if result.is_correct else '✗'} {result.explanation}")

            except (ValueError, IndexError) as e:
                print(f"\nInvalid input: {e}")
                continue

        # Save performance history if using adaptive session
        if args.adaptive and hasattr(session, "save_performance_history"):
            session.save_performance_history()

        session.save_wrong_answers()
        summary = session.get_summary()
        print("\n=== Quiz Summary ===")
        print(f"Answered: {summary['answered']}/{summary['total_questions']}")
        print(f"Correct: {summary['correct']} | Wrong: {summary['wrong']}")
        print(f"Points: {summary['earned_points']:.1f}/{summary['total_points']:.1f}")
        print(f"Accuracy: {summary['accuracy']:.1f}%")

        # Print performance summary if using adaptive session
        if args.adaptive and hasattr(session, "get_progress_summary"):
            print("\n=== Performance Summary ===")
            perf_summary = session.get_progress_summary()
            for qid, stats in list(perf_summary["performance_by_question"].items())[:5]:  # Show first 5
                print(
                    f"{qid}: {stats['correct_count']} correct, {stats['incorrect_count']} incorrect, "
                    f"{stats['success_rate']:.2f} success rate"
                )
            if len(perf_summary["performance_by_question"]) > 5:
                print(f"... and {len(perf_summary['performance_by_question']) - 5} more questions")
    else:
        print(
            "Usage: quizbase --create-sample | --file <quiz.json> [--random] [--adaptive] "
            "[--history-file <file>] [--wrong <file>]"
        )


@dataclass
class QuestionPerformance:
    """Track performance statistics for a single question."""

    question_id: str
    correct_count: int = 0
    incorrect_count: int = 0
    total_attempts: int = 0

    def get_success_rate(self) -> float:
        """Get success rate (0.0 to 1.0)."""
        if self.total_attempts == 0:
            return 0.5  # Default to 50% if no attempts
        return self.correct_count / self.total_attempts

    def get_weight(self) -> float:
        """
        Calculate weight for adaptive selection.

        Lower weight for well-performed questions, higher weight for poorly performed questions.
        """
        success_rate = self.get_success_rate()
        return (1.0 - success_rate) + 0.1


@dataclass
class AdaptiveQuizSession(QuizSession):
    """Quiz session with adaptive question selection based on user performance."""

    # Track user performance for each question
    performance_history: dict[str, QuestionPerformance] = field(default_factory=dict)
    # File to save/load performance history
    history_file: str = "user_performance.json"
    # Flag to control adaptive behavior
    adaptive_mode: bool = True

    def __post_init__(self):
        """Initialize after dataclass fields are set."""
        if not self.performance_history:
            self.performance_history = {}

    def load_performance_history(self, file_path: str | Path | None = None) -> None:
        """Load user performance history from file."""
        path = Path(file_path) if file_path else Path(self.history_file)

        if path.exists():
            try:
                with open(path, encoding="utf-8") as f:
                    data = json.load(f)

                for qid, perf_data in data.items():
                    self.performance_history[qid] = QuestionPerformance(
                        question_id=qid,
                        correct_count=perf_data.get("correct_count", 0),
                        incorrect_count=perf_data.get("incorrect_count", 0),
                        total_attempts=perf_data.get("total_attempts", 0),
                    )
            except (json.JSONDecodeError, KeyError) as e:
                print(f"Could not load performance history: {e}")
                self.performance_history = {}
        else:
            self.performance_history = {}

    def save_performance_history(self, file_path: str | Path | None = None) -> None:
        """Save user performance history to file."""
        path = Path(file_path) if file_path else Path(self.history_file)

        data = {}
        for qid, perf in self.performance_history.items():
            data[qid] = {
                "correct_count": perf.correct_count,
                "incorrect_count": perf.incorrect_count,
                "total_attempts": perf.total_attempts,
            }

        with open(path, "w", encoding="utf-8") as f:
            json.dump(data, f, indent=2, ensure_ascii=False)

    def update_performance(self, question: Question, is_correct: bool) -> None:
        """Update performance statistics for a question."""
        qid = question.question_id

        if qid not in self.performance_history:
            self.performance_history[qid] = QuestionPerformance(question_id=qid)

        perf = self.performance_history[qid]
        perf.total_attempts += 1

        if is_correct:
            perf.correct_count += 1
        else:
            perf.incorrect_count += 1

    def get_adaptive_question_indices(self) -> list[int]:
        """Get question indices with adaptive weighting based on performance."""
        if not self.questions:
            return []

        # If we don't have performance data for all questions, use uniform distribution initially
        all_have_data = all(q.question_id in self.performance_history for q in self.questions)

        if not all_have_data:
            # Return shuffled indices for initial uniform exposure
            indices = list(range(len(self.questions)))
            random.shuffle(indices)
            return indices

        # Calculate weights for each question based on performance
        weights = []
        for _, question in enumerate(self.questions):
            perf = self.performance_history.get(question.question_id)
            weight = perf.get_weight() if perf else 0.5
            weights.append(weight)

        # Normalize weights to probabilities
        total_weight = sum(weights)
        if total_weight == 0:
            # If all weights are zero, use uniform distribution
            probabilities = [1.0 / len(weights)] * len(weights)
        else:
            probabilities = [w / total_weight for w in weights]

        # Create a weighted shuffle of indices
        indices = list(range(len(self.questions)))
        adaptive_indices = []
        remaining_indices = indices[:]
        remaining_probs = probabilities[:]

        # Use weighted selection without replacement to create order
        while remaining_indices:
            # Normalize remaining probabilities
            total_remaining_prob = sum(remaining_probs)
            if total_remaining_prob == 0:
                # Fallback to random selection if all probs are 0
                selected_idx = random.randint(0, len(remaining_indices) - 1)
            else:
                norm_probs = [p / total_remaining_prob for p in remaining_probs]
                selected_idx = random.choices(range(len(remaining_indices)), weights=norm_probs)[0]

            # Add selected index to result and remove from remaining
            adaptive_indices.append(remaining_indices.pop(selected_idx))
            remaining_probs.pop(selected_idx)

        return adaptive_indices

    def submit_answer(self, answer: Any) -> QuizResult | None:
        """Submit answer and update performance tracking."""
        question = self.get_current_question()
        if question is None:
            return None

        is_correct, explanation = question.check_answer(answer)
        result = QuizResult(
            question=question,
            user_answer=answer,
            is_correct=is_correct,
            explanation=explanation,
        )

        # Update performance history before appending to results
        self.update_performance(question, is_correct)

        self.results.append(result)
        self._current_index += 1
        return result

    def reset(self, random_order: bool | None = None) -> None:
        """Reset quiz session while preserving performance history."""
        self._current_index = 0
        self.results = []

        if random_order is not None:
            self.random_order = random_order

        # Re-initialize order based on adaptive algorithm if enabled
        self._initialize_order()

    def _initialize_order(self) -> None:
        """Initialize question order based on settings and performance."""
        if self.adaptive_mode and self.random_order:
            # Use adaptive ordering if we have performance data, otherwise random
            self._shuffled_indices = self.get_adaptive_question_indices()
        else:
            # Use regular random or sequential ordering
            if self.random_order:
                self._shuffled_indices = list(range(self.total_questions))
                random.shuffle(self._shuffled_indices)
            else:
                self._shuffled_indices = list(range(self.total_questions))

    def get_progress_summary(self) -> dict[str, Any]:
        """Get detailed progress summary for all questions."""
        summary = {
            "total_questions": self.total_questions,
            "answered_questions": len(self.results),
            "performance_by_question": {},
            "overall_accuracy": self.accuracy,
        }

        for question in self.questions:
            perf = self.performance_history.get(question.question_id)
            if perf:
                summary["performance_by_question"][question.question_id] = {
                    "question_text": question.question_text,
                    "correct_count": perf.correct_count,
                    "incorrect_count": perf.incorrect_count,
                    "total_attempts": perf.total_attempts,
                    "success_rate": perf.get_success_rate(),
                    "weight_for_selection": perf.get_weight(),
                }
            else:
                summary["performance_by_question"][question.question_id] = {
                    "question_text": question.question_text,
                    "correct_count": 0,
                    "incorrect_count": 0,
                    "total_attempts": 0,
                    "success_rate": 0.0,
                    "weight_for_selection": 0.5,
                }

        return summary


if __name__ == "__main__":
    main()
