from app import db
from datetime import datetime
import json

class VocabularyQuiz(db.Model):
    """Model for storing vocabulary quizzes generated for students"""
    __tablename__ = 'vocabulary_quizzes'
    
    id = db.Column(db.Integer, primary_key=True)
    student_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    topic_id = db.Column(db.Integer, db.ForeignKey('topics.id'), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    completed_at = db.Column(db.DateTime, nullable=True)
    score = db.Column(db.Integer, nullable=True)  # Score out of 100
    words_learned = db.Column(db.Integer, nullable=True)  # Number of words marked as learned
    
    # Relationships
    questions = db.relationship('QuizQuestion', backref='quiz', lazy=True, cascade='all, delete-orphan')
    
    def __repr__(self):
        return f'<VocabularyQuiz #{self.id} for Topic #{self.topic_id}, Student #{self.student_id}>'
    
    def is_pending(self):
        """Check if the quiz is pending (created but not completed)"""
        return self.completed_at is None
    
    def is_completed(self):
        """Check if the quiz has been completed"""
        return self.completed_at is not None
    
    def calculate_score(self):
        """Calculate score based on correct answers"""
        if not self.questions:
            return 0
            
        correct_answers = sum(1 for q in self.questions if q.is_correct)
        total_questions = len(self.questions)
        
        if total_questions == 0:
            return 0
            
        return int((correct_answers / total_questions) * 100)
    
    def count_words_learned(self):
        """Count the number of words marked as learned"""
        return sum(1 for q in self.questions if q.is_correct)
    
    def complete_quiz(self):
        """Mark the quiz as completed and calculate score and words learned"""
        if not self.is_completed():
            self.completed_at = datetime.utcnow()
            self.score = self.calculate_score()
            self.words_learned = self.count_words_learned()
    
    def to_dict(self):
        """Convert model to dictionary for API responses"""
        return {
            'id': self.id,
            'student_id': self.student_id,
            'topic_id': self.topic_id,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
            'completed_at': self.completed_at.strftime('%Y-%m-%d %H:%M:%S') if self.completed_at else None,
            'score': self.score,
            'words_learned': self.words_learned,
            'questions': [q.to_dict() for q in self.questions]
        }


class QuizQuestion(db.Model):
    """Model for storing individual vocabulary quiz questions"""
    __tablename__ = 'quiz_questions'
    
    id = db.Column(db.Integer, primary_key=True)
    quiz_id = db.Column(db.Integer, db.ForeignKey('vocabulary_quizzes.id'), nullable=False)
    word = db.Column(db.String(100), nullable=False)  # The word being tested
    context = db.Column(db.Text, nullable=True)  # Context sentence from the reading content
    question_text = db.Column(db.Text, nullable=False)  # The question text (usually "What does [word] mean?")
    correct_answer = db.Column(db.Text, nullable=False)  # The correct answer (definition)
    options = db.Column(db.Text, nullable=False)  # JSON string of options including correct answer
    student_answer = db.Column(db.Text, nullable=True)  # Student's selected answer
    is_correct = db.Column(db.Boolean, nullable=True)  # Whether student's answer was correct
    
    def __repr__(self):
        return f'<QuizQuestion #{self.id} for Quiz #{self.quiz_id} - Word: {self.word}>'
    
    def get_options(self):
        """Get the options as a list"""
        try:
            return json.loads(self.options)
        except:
            return []
    
    def set_options(self, options_list):
        """Set the options from a list"""
        self.options = json.dumps(options_list)
    
    def check_answer(self, student_answer):
        """Check if the student's answer is correct"""
        self.student_answer = student_answer
        self.is_correct = (student_answer == self.correct_answer)
        return self.is_correct
    
    def to_dict(self):
        """Convert model to dictionary for API responses"""
        return {
            'id': self.id,
            'quiz_id': self.quiz_id,
            'word': self.word,
            'context': self.context,
            'question_text': self.question_text,
            'options': self.get_options(),
            'student_answer': self.student_answer,
            'is_correct': self.is_correct
        }


class TeacherQuiz(db.Model):
    """Model for teacher-created quizzes"""
    __tablename__ = 'teacher_quizzes'

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), nullable=False)
    description = db.Column(db.Text)
    quiz_type = db.Column(db.String(10), nullable=False)  # 'mcq' or 'qa'
    created_by_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    created_by = db.relationship('User', backref='teacher_quizzes')
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    questions = db.relationship('TeacherQuestion', backref='quiz', lazy=True, cascade='all, delete-orphan')

    def __repr__(self):
        return f'<TeacherQuiz {self.title}>'


class TeacherQuestion(db.Model):
    """Model for teacher-created quiz questions"""
    __tablename__ = 'teacher_questions'

    id = db.Column(db.Integer, primary_key=True)
    quiz_id = db.Column(db.Integer, db.ForeignKey('teacher_quizzes.id'), nullable=False)
    question_text = db.Column(db.Text, nullable=False)
    question_type = db.Column(db.String(10), nullable=False)  # 'mcq' or 'qa'

    # For MCQ
    options = db.Column(db.Text)  # JSON string for options list
    correct_answer = db.Column(db.String(500))  # For MCQ, the correct option text

    # For QA
    expected_answer = db.Column(db.Text)  # For QA, the expected answer

    def __repr__(self):
        return f'<TeacherQuestion {self.question_text[:50]}...>'

    def get_options(self):
        """Get the options as a list"""
        try:
            return json.loads(self.options) if self.options else []
        except:
            return []

    def set_options(self, options_list):
        """Set the options from a list"""
        self.options = json.dumps(options_list) if options_list else None


class QuizAttempt(db.Model):
    """Model for tracking student attempts on teacher-created quizzes"""
    __tablename__ = 'quiz_attempts'

    id = db.Column(db.Integer, primary_key=True)
    student_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    quiz_id = db.Column(db.Integer, db.ForeignKey('teacher_quizzes.id'), nullable=False)
    attempted_at = db.Column(db.DateTime, default=datetime.utcnow)
    score = db.Column(db.Integer, nullable=False)  # Score out of total questions
    total_questions = db.Column(db.Integer, nullable=False)
    percentage = db.Column(db.Float, nullable=False)  # Score percentage
    answers = db.Column(db.Text)  # JSON string of student's answers

    # Relationships
    student = db.relationship('User', backref='quiz_attempts')
    quiz = db.relationship('TeacherQuiz', backref='attempts')

    def __repr__(self):
        return f'<QuizAttempt Student #{self.student_id} on Quiz #{self.quiz_id} - Score: {self.score}/{self.total_questions}>'

    def get_answers(self):
        """Get the answers as a dictionary"""
        try:
            return json.loads(self.answers) if self.answers else {}
        except:
            return {}

    def set_answers(self, answers_dict):
        """Set the answers from a dictionary"""
        self.answers = json.dumps(answers_dict) if answers_dict else None