from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from django.shortcuts import get_object_or_404, redirect, render
from django.contrib import messages
from .models import Quiz, Question, Answer, Option, CompletedQuiz
from apps.carers.models import Profile
from django.utils.timezone import now

from .. import quiz


@login_required
def quiz_view(request, quiz_id):
    """
    Displays a paginated view of the quiz questions, 3 questions per page.
    Allows users to save their answers, navigate between pages, and resume the quiz.
    """
    # Get the quiz and the user's profile
    quiz = get_object_or_404(Quiz, id=quiz_id)
    profile = get_object_or_404(Profile, user=request.user)

    # Fetch all questions for the quiz and paginate them
    questions = quiz.questions.order_by('id')
    paginator = Paginator(questions, 3)  # 3 questions per page

    # Determine the current page
    answered_questions_count = Answer.objects.filter(profile=profile, question__quiz=quiz).count()
    total_questions = quiz.questions.count()

    # Default to the first page with unanswered questions
    page_number = request.GET.get('page')
    if not page_number:
        if answered_questions_count < total_questions:
            page_number = (answered_questions_count // 3) + 1  # Redirect to the first unanswered page
        else:
            page_number = 1  # Start from the first page if all questions are answered

    page_obj = paginator.get_page(page_number)

    # Force evaluation of current questions as a list and extract their IDs
    current_questions = list(page_obj.object_list)
    question_ids = [q.id for q in current_questions]

    # Fetch user's existing answers using a list of IDs instead of a QuerySet subquery
    user_answers = Answer.objects.filter(profile=profile, question__in=question_ids)

    # Create a dictionary for quick lookup of user answers by question id
    answers_dict = {answer.question_id: answer for answer in user_answers}
    for question in current_questions:
        question.user_answer = answers_dict.get(question.id)

    # Calculate progress as a percentage
    progress_percentage = int((page_obj.number / paginator.num_pages) * 100)

    # Handle GET request to render the page
    if request.method == 'GET':
        context = {
            'quiz': quiz,
            'current_questions': current_questions,
            'page_obj': page_obj,  # Paginator object for navigation
            'progress_percentage': progress_percentage,  # Pass progress percentage to the template
        }
        return render(request, 'quiz/quiz.html', context)
    errors_occurred = False
    # Handle POST request to save answers
    if request.method == 'POST':
        for key, value in request.POST.items():
            if key.startswith('question_'):
                question_id = int(key.split('_')[1])
                question = get_object_or_404(Question, id=question_id, quiz=quiz)

                try:
                    # Save answers based on question type
                    if question.question_type == 1:  # Multiple Select
                        selected_option_ids = request.POST.getlist(f'question_{question.id}')
                        answer, created = Answer.objects.get_or_create(
                            profile=profile, question=question, answer_type=3
                        )
                        answer.selected_options.set(Option.objects.filter(id__in=selected_option_ids))
                        answer.full_clean()
                        answer.save()

                    elif question.question_type == 2:  # Single Select
                        selected_option_id = value
                        answer, created = Answer.objects.get_or_create(
                            profile=profile, question=question, answer_type=2
                        )
                        answer.selected_option = Option.objects.get(id=selected_option_id)
                        answer.full_clean()
                        answer.save()

                    elif question.question_type == 3:  # Written Answer
                        answer_text = value
                        answer, created = Answer.objects.get_or_create(
                            profile=profile, question=question, answer_type=1
                        )
                        answer.answer_text = answer_text
                        answer.full_clean()
                        answer.save()

                except Exception as e:
                    errors_occurred = True  # Mark that an error occurred
                    question.error = e
                    messages.error(request, f"Error saving answer for question '{question.question_text}': {e}")

        # If errors occurred, re-render the same page with errors
        if errors_occurred:
            context = {
                'quiz': quiz,
                'current_questions': current_questions,
                'page_obj': page_obj,  # Paginator object for navigation
                'progress_percentage': progress_percentage,  # Pass progress percentage to the template
            }
            return render(request, 'quiz/quiz.html', context)


        # Handle navigation based on "previous" or "next" buttons
        next_page = request.POST.get('next')
        previous_page = request.POST.get('previous')

        if previous_page:
            # Redirect to the previous page
            return redirect(f"{request.path}?page={previous_page}")
        elif next_page:
            # Redirect to the next page
            return redirect(f"{request.path}?page={next_page}")

        # Handle quiz submission on the last page
        if not page_obj.has_next():
            # Set the quiz completion date
            CompletedQuiz.objects.create(profile=profile, quiz=quiz)
            messages.success(request, "Quiz submitted successfully!")
            return redirect('profile')  # Redirect to the profile page or another appropriate view

        # Default redirect back to the same page
        return redirect(request.path)


@login_required
def quiz_start(request, quiz_id):
    quiz = get_object_or_404(Quiz, pk=quiz_id)
    context = {
        'quiz': quiz,
               }
    return render(request, 'quiz/quiz_intro.html', context=context)
