from flask import render_template, redirect, url_for, flash, request, jsonify
from flask_login import current_user, login_required

from app import db
from app.routes.student import student_bp
from app.utils.decorators import student_required
from app.models.topic import Topic
from app.models.progress import Progress
from app.models.quiz import VocabularyQuiz, QuizQuestion
from app.models.vocabulary import Vocabulary
import logging
import json
from datetime import datetime

logger = logging.getLogger(__name__)

# Helper function to get pending quizzes for the current user
def get_pending_quizzes(user_id):
    return VocabularyQuiz.query.filter_by(
        student_id=user_id, 
        completed_at=None
    ).order_by(
        VocabularyQuiz.created_at.desc()
    ).all()

# Helper function to get completed quizzes for the current user
def get_completed_quizzes(user_id):
    return VocabularyQuiz.query.filter(
        VocabularyQuiz.student_id == user_id,
        VocabularyQuiz.completed_at != None
    ).order_by(
        VocabularyQuiz.completed_at.desc()
    ).all()

@student_bp.route('/vocabulary-quiz/generate/<int:topic_id>', methods=['POST'])
@login_required
@student_required
def generate_vocabulary_quiz(topic_id):
    """Generate a vocabulary quiz for the specified topic"""
    try:
        # Check if the topic exists
        topic = Topic.query.get_or_404(topic_id)
        
        # Check if there's already a pending quiz for this topic
        existing_quiz = VocabularyQuiz.query.filter_by(
            student_id=current_user.id,
            topic_id=topic_id,
            completed_at=None
        ).first()
        
        if existing_quiz:
            flash('You already have a pending vocabulary quiz for this topic.', 'info')
            return redirect(url_for('student.vocabulary_quiz_take', quiz_id=existing_quiz.id))
        
        # Check if the topic has been started
        progress = Progress.query.filter_by(
            student_id=current_user.id,
            topic_id=topic_id
        ).first()
        
        if not progress or (not progress.reading_started and 
                          not progress.speaking_started and 
                          not progress.comprehension_started):
            flash('You need to start this topic before generating a vocabulary quiz.', 'warning')
            return redirect(url_for('student.vocabulary_quiz_list'))
        
        # Generate quiz questions using AI
        from app.services.ai_assessment import get_ai_assessor
        ai = get_ai_assessor()
        quiz_questions = ai.generate_vocabulary_quiz(topic.reading_content)
        
        if not quiz_questions or len(quiz_questions) == 0:
            flash('Failed to generate vocabulary quiz. Please try again later.', 'danger')
            return redirect(url_for('student.vocabulary_quiz_list'))
        
        # Create new quiz
        quiz = VocabularyQuiz(
            student_id=current_user.id,
            topic_id=topic_id,
        )
        
        # Add questions to quiz
        for question in quiz_questions:
            question.quiz = quiz
        
        # Save to database
        db.session.add(quiz)
        db.session.commit()
        
        flash('Vocabulary quiz created successfully!', 'success')
        return redirect(url_for('student.vocabulary_quiz_take', quiz_id=quiz.id))
        
    except Exception as e:
        db.session.rollback()
        logger.error(f"Error generating vocabulary quiz: {str(e)}")
        flash('An error occurred while generating the quiz. Please try again.', 'danger')
        return redirect(url_for('student.topic_view', topic_id=topic_id))

@student_bp.route('/vocabulary-quiz/take/<int:quiz_id>')
@login_required
@student_required
def vocabulary_quiz_take(quiz_id):
    """Display the vocabulary quiz for the student to take"""
    quiz = VocabularyQuiz.query.get_or_404(quiz_id)
    
    # Ensure the quiz belongs to the current user
    if quiz.student_id != current_user.id:
        flash('You do not have permission to access this quiz.', 'danger')
        return redirect(url_for('student.dashboard'))
    
    # If quiz is already completed, redirect to results
    if quiz.is_completed():
        return redirect(url_for('student.vocabulary_quiz_results', quiz_id=quiz_id))
    
    topic = Topic.query.get(quiz.topic_id)
    
    return render_template('student/vocabulary_quiz_take.html', 
                          quiz=quiz, 
                          questions=quiz.questions,
                          topic=topic)

@student_bp.route('/vocabulary-quiz/submit/<int:quiz_id>', methods=['POST'])
@login_required
@student_required
def vocabulary_quiz_submit(quiz_id):
    """Process the submitted vocabulary quiz answers"""
    quiz = VocabularyQuiz.query.get_or_404(quiz_id)
    
    # Ensure the quiz belongs to the current user and is not already completed
    if quiz.student_id != current_user.id:
        flash('You do not have permission to submit this quiz.', 'danger')
        return redirect(url_for('student.dashboard'))
    
    if quiz.is_completed():
        flash('This quiz has already been completed.', 'info')
        return redirect(url_for('student.vocabulary_quiz_results', quiz_id=quiz_id))
    
    # Process each question
    for question in quiz.questions:
        answer = request.form.get(f'question_{question.id}')
        if answer:
            question.check_answer(answer)
    
    # Mark quiz as completed
    quiz.complete_quiz()
    
    # Add correctly answered words to user's vocabulary
    for question in quiz.questions:
        if question.is_correct:
            # Check if word already exists in vocabulary
            existing_word = Vocabulary.query.filter_by(
                student_id=current_user.id,
                word=question.word
            ).first()
            
            if not existing_word:
                # Add new word to vocabulary
                new_word = Vocabulary(
                    student_id=current_user.id,
                    word=question.word,
                    definition=question.correct_answer,
                    context=question.context,
                    source=f"Quiz from topic '{Topic.query.get(quiz.topic_id).title}'"
                )
                db.session.add(new_word)
    
    db.session.commit()
    flash('Quiz submitted successfully!', 'success')
    return redirect(url_for('student.vocabulary_quiz_results', quiz_id=quiz_id))

@student_bp.route('/vocabulary-quiz/results/<int:quiz_id>')
@login_required
@student_required
def vocabulary_quiz_results(quiz_id):
    """Show the results of a completed vocabulary quiz"""
    quiz = VocabularyQuiz.query.get_or_404(quiz_id)
    
    # Ensure the quiz belongs to the current user
    if quiz.student_id != current_user.id:
        flash('You do not have permission to view these results.', 'danger')
        return redirect(url_for('student.dashboard'))
    
    # If quiz is not completed yet, redirect to take the quiz
    if not quiz.is_completed():
        flash('Please complete the quiz to view results.', 'info')
        return redirect(url_for('student.vocabulary_quiz_take', quiz_id=quiz_id))
    
    topic = Topic.query.get(quiz.topic_id)
    
    return render_template('student/vocabulary_quiz_results.html',
                          quiz=quiz,
                          questions=quiz.questions,
                          topic=topic)

@student_bp.route('/vocabulary-quiz/list')
@login_required
@student_required
def vocabulary_quiz_list():
    """Show a list of all vocabulary quizzes for the current user"""
    pending_quizzes = get_pending_quizzes(current_user.id)
    completed_quizzes = get_completed_quizzes(current_user.id)
    
    # Get all topics
    all_topics = Topic.query.order_by(Topic.category, Topic.created_at).all()
    
    # Get progress for all topics
    progress_dict = {
        p.topic_id: p for p in Progress.query.filter_by(student_id=current_user.id).all()
    }
    
    # Create a list of topic data with quiz status
    topic_data = []
    for topic in all_topics:
        # Check if this topic has a pending quiz
        pending_quiz = next((q for q in pending_quizzes if q.topic_id == topic.id), None)
        
        # Check if this topic has any completed quizzes
        completed_quiz = next((q for q in completed_quizzes if q.topic_id == topic.id), None)
        
        # Check if the topic has been started
        progress = progress_dict.get(topic.id)
        is_started = progress is not None and (
            progress.reading_started or 
            progress.speaking_started or 
            progress.comprehension_started
        )
        
        # Add to topic data list
        topic_data.append({
            'id': topic.id,
            'title': topic.title,
            'category': topic.category if topic.category is not None else "General",
            'is_started': is_started,
            'pending_quiz': pending_quiz,
            'completed_quiz': completed_quiz,
            'is_locked': not is_started
        })
    
    # Group topics by category
    categories = {}
    for topic in topic_data:
        if topic['category'] not in categories:
            categories[topic['category']] = []
        categories[topic['category']].append(topic)
    
    # Get topic titles for existing quizzes
    topics = {}
    quiz_topic_ids = [q.topic_id for q in pending_quizzes + completed_quizzes]
    if quiz_topic_ids:
        topic_records = Topic.query.filter(Topic.id.in_(quiz_topic_ids)).all()
        topics = {t.id: t.title for t in topic_records}
    
    return render_template('student/vocabulary_quiz_list.html',
                          pending_quizzes=pending_quizzes,
                          completed_quizzes=completed_quizzes,
                          topics=topics,
                          topic_data=topic_data,
                          categories=categories)

# Add a function to get pending quiz count for the dashboard
def get_pending_quiz_count(user_id):
    return VocabularyQuiz.query.filter_by(
        student_id=user_id, 
        completed_at=None
    ).count()

# Add a function to get recent completed quizzes for the dashboard
def get_recent_completed_quizzes(user_id, limit=3):
    return VocabularyQuiz.query.filter(
        VocabularyQuiz.student_id == user_id,
        VocabularyQuiz.completed_at != None
    ).order_by(
        VocabularyQuiz.completed_at.desc()
    ).limit(limit).all()