from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from django.http import HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils import timezone

from courses.models import Category, Course, Lesson, Evaluation, Module
from .models import Enrollment, LessonProgress
from certificates.models import Certificate


@login_required(login_url="users:login")
def portal_catalog_view(request):
    """
    Catálogo interno para alumnos en el Campus Virtual.
    """
    categories = Category.objects.all()
    courses = Course.objects.filter(is_published=True).select_related("category")

    category_slug = request.GET.get("category")
    query = request.GET.get("q")

    if category_slug:
        courses = courses.filter(category__slug=category_slug)
    if query:
        courses = courses.filter(
            Q(title__icontains=query)
            | Q(short_description__icontains=query)
            | Q(iso_standard__icontains=query)
            | Q(description__icontains=query)
        )

    enrolled_course_ids = set(Enrollment.objects.filter(user=request.user).values_list("course_id", flat=True))

    context = {
        "categories": categories,
        "courses": courses,
        "selected_category": category_slug,
        "search_query": query or "",
        "enrolled_course_ids": enrolled_course_ids,
    }
    return render(request, "pages/portal_catalog.html", context)


@login_required
def enroll_course_view(request, slug):
    """
    Procesar inscripción / matrícula del técnico al curso.
    """
    if request.method != "POST":
        return redirect("courses:course_detail", slug=slug)

    course = get_object_or_404(Course, slug=slug, is_published=True)
    enrollment, created = Enrollment.objects.get_or_create(user=request.user, course=course)

    if created:
        for module in course.modules.all():
            for lesson in module.lessons.all():
                LessonProgress.objects.get_or_create(enrollment=enrollment, lesson=lesson)
        messages.success(request, f"¡Te has matriculado exitosamente en {course.title}!")
    else:
        messages.info(request, "Ya te encontrabas inscrito en este programa.")

    first_module = course.modules.first()
    if first_module and first_module.lessons.exists():
        first_lesson = first_module.lessons.first()
        return redirect("campus:lesson_player", slug=course.slug, lesson_slug=first_lesson.slug)

    return redirect("courses:course_detail", slug=course.slug)


@login_required
def course_resume_view(request, slug):
    """
    Enrutador inteligente: Lleva al alumno a su lección pendiente o a la primera lección del curso.
    """
    course = get_object_or_404(Course.objects.prefetch_related("modules__lessons"), slug=slug, is_published=True)
    enrollment, _ = Enrollment.objects.get_or_create(user=request.user, course=course)

    all_lessons = list(Lesson.objects.filter(module__course=course).order_by("module__order", "order", "id"))
    if not all_lessons:
        return redirect("courses:course_detail", slug=course.slug)

    for l in all_lessons:
        LessonProgress.objects.get_or_create(enrollment=enrollment, lesson=l)

    completed_lesson_ids = set(LessonProgress.objects.filter(enrollment=enrollment, is_completed=True).values_list("lesson_id", flat=True))

    target_lesson = None
    for l in all_lessons:
        if l.id not in completed_lesson_ids:
            target_lesson = l
            break

    if not target_lesson:
        target_lesson = all_lessons[0]

    return redirect("campus:lesson_player", slug=course.slug, lesson_slug=target_lesson.slug)


@login_required
def lesson_player_view(request, slug, lesson_slug):
    """
    Aula Virtual / Reproductor de video y material de estudio de una lección.
    """
    course = get_object_or_404(Course.objects.prefetch_related("modules__lessons"), slug=slug, is_published=True)
    lesson = get_object_or_404(Lesson.objects.select_related("module"), module__course=course, slug=lesson_slug)

    enrollment, _ = Enrollment.objects.get_or_create(user=request.user, course=course)
    progress, _ = LessonProgress.objects.get_or_create(enrollment=enrollment, lesson=lesson)

    all_lessons = list(Lesson.objects.filter(module__course=course).order_by("module__order", "order", "id"))
    current_index = all_lessons.index(lesson) if lesson in all_lessons else 0
    prev_lesson = all_lessons[current_index - 1] if current_index > 0 else None
    next_lesson = all_lessons[current_index + 1] if current_index < len(all_lessons) - 1 else None

    progress_map = {
        lp.lesson_id: lp.is_completed
        for lp in LessonProgress.objects.filter(enrollment=enrollment)
    }

    first_evaluation = course.evaluations.first()

    context = {
        "course": course,
        "lesson": lesson,
        "enrollment": enrollment,
        "progress": progress,
        "prev_lesson": prev_lesson,
        "next_lesson": next_lesson,
        "progress_map": progress_map,
        "progress_percent": enrollment.get_progress_percentage(),
        "first_evaluation": first_evaluation,
    }
    return render(request, "pages/lesson_player.html", context)


@login_required
def lesson_toggle_progress_view(request, lesson_id):
    """
    AJAX / HTMX o POST para marcar una lección como completada.
    """
    if request.method != "POST":
        return redirect("campus:my_learning")

    lesson = get_object_or_404(Lesson.objects.select_related("module__course"), id=lesson_id)
    course = lesson.module.course
    enrollment = get_object_or_404(Enrollment, user=request.user, course=course)

    progress, _ = LessonProgress.objects.get_or_create(enrollment=enrollment, lesson=lesson)
    progress.is_completed = not progress.is_completed
    if progress.is_completed:
        progress.completed_at = timezone.now()
    else:
        progress.completed_at = None
    progress.save()

    if request.headers.get("HX-Request"):
        all_lessons = list(Lesson.objects.filter(module__course=course).order_by("module__order", "order", "id"))
        current_index = all_lessons.index(lesson) if lesson in all_lessons else 0
        next_lesson = all_lessons[current_index + 1] if current_index < len(all_lessons) - 1 else None

        if progress.is_completed and next_lesson:
            return HttpResponse(status=204, headers={"HX-Redirect": reverse("campus:lesson_player", kwargs={"slug": course.slug, "lesson_slug": next_lesson.slug})})

    return redirect("campus:lesson_player", slug=course.slug, lesson_slug=lesson.slug)


@login_required
def my_learning_view(request):
    """
    Portal / Dashboard del Alumno (/mi-aprendizaje/).
    """
    enrollments = Enrollment.objects.filter(user=request.user).select_related("course", "certificate").order_by("-enrolled_at")

    in_progress = []
    completed = []

    for enroll in enrollments:
        percent = enroll.get_progress_percentage()
        if hasattr(enroll, "certificate") and enroll.certificate:
            completed.append({"enrollment": enroll, "percent": 100})
        elif percent >= 100:
            completed.append({"enrollment": enroll, "percent": 100})
        else:
            in_progress.append({"enrollment": enroll, "percent": percent})

    context = {
        "in_progress": in_progress,
        "completed": completed,
    }
    return render(request, "pages/my_learning.html", context)


@login_required
def quiz_detail_view(request, slug, evaluation_id):
    course = get_object_or_404(Course, slug=slug)
    evaluation = get_object_or_404(Evaluation, id=evaluation_id, course=course)
    enrollment, _ = Enrollment.objects.get_or_create(user=request.user, course=course)

    context = {
        "course": course,
        "evaluation": evaluation,
        "enrollment": enrollment,
        "questions_count": len(evaluation.questions) if isinstance(evaluation.questions, list) else 0,
    }
    return render(request, "pages/quiz.html", context)


@login_required
def quiz_submit_view(request, slug, evaluation_id):
    if request.method != "POST":
        return redirect("campus:quiz_detail", slug=slug, evaluation_id=evaluation_id)

    course = get_object_or_404(Course, slug=slug)
    evaluation = get_object_or_404(Evaluation, id=evaluation_id, course=course)
    enrollment, _ = Enrollment.objects.get_or_create(user=request.user, course=course)

    questions = evaluation.questions if isinstance(evaluation.questions, list) else []
    total_questions = len(questions)
    if total_questions == 0:
        messages.error(request, "Este examen no tiene preguntas configuradas.")
        return redirect("courses:course_detail", slug=slug)

    correct_count = 0
    results_detail = []

    for idx, q in enumerate(questions):
        q_id = str(q.get("id", idx + 1))
        user_answer_idx = request.POST.get(f"question_{q_id}")
        correct_idx = q.get("correct")

        is_correct = False
        if user_answer_idx is not None and str(user_answer_idx) == str(correct_idx):
            is_correct = True
            correct_count += 1

        results_detail.append({
            "id": q_id,
            "text": q.get("text", ""),
            "user_answer": user_answer_idx,
            "correct_answer": correct_idx,
            "is_correct": is_correct,
        })

    score_percentage = int((correct_count / total_questions) * 100) if total_questions > 0 else 0
    passed = score_percentage >= evaluation.passing_score

    certificate = None
    if passed:
        certificate, created = Certificate.objects.get_or_create(enrollment=enrollment)
        for lesson in Lesson.objects.filter(module__course=course):
            LessonProgress.objects.update_or_create(
                enrollment=enrollment,
                lesson=lesson,
                defaults={"is_completed": True}
            )

    if request.headers.get("HX-Request") == "true":
        return JsonResponse({
            "score": score_percentage,
            "passed": passed,
            "correct_count": correct_count,
            "total_questions": total_questions,
            "certificate_code": certificate.certificate_code if certificate else None,
            "certificate_url": reverse("certificates:download", args=[certificate.certificate_code]) if certificate else None,
        })

    context = {
        "course": course,
        "evaluation": evaluation,
        "score": score_percentage,
        "passed": passed,
        "correct_count": correct_count,
        "total_questions": total_questions,
        "certificate": certificate,
        "results_detail": results_detail,
    }
    return render(request, "pages/quiz_result.html", context)
