"""
analytics/views.py
==================
Vistas de analítica pedagógica.

Proporciona datos agregados sobre participación, comprensión y riesgo.
La mayoría son cálculos sobre datos existentes (Respuesta, DudaAlumno)
sin necesitar modelos propios para los datos en tiempo real.

Para producción de alto volumen: mover los cálculos pesados a
tareas Celery que corren en background y cachear en Redis.
"""

import logging
from django.db.models import Avg, Count, Q
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated

from sessions.models import Sesion, Respuesta, PreguntaActiva
from analytics.models import AlertaRiesgo, ConceptoConfuso
from shared.permissions import IsApprovedDocente
from shared.utils.responses import success_response, error_response

logger = logging.getLogger('eduplay')


class MapaCalorView(APIView):
    """
    GET /analytics/mapa-calor/?seccion_id=N
    Calcula el porcentaje de acierto por tema/unidad para la sección.
    """
    permission_classes = [IsApprovedDocente]

    def get(self, request):
        seccion_id = request.query_params.get('seccion_id')
        if not seccion_id:
            return error_response(message='seccion_id requerido.', status_code=400)

        # Agrupar respuestas por unidad de la pregunta
        datos = (
            Respuesta.objects
            .filter(
                pregunta_activa__sesion__seccion_id=seccion_id,
                pregunta_activa__sesion__docente=request.user,
                es_correcta__isnull=False,
            )
            .values('pregunta_activa__pregunta__unidad')
            .annotate(
                total=Count('id'),
                correctas=Count('id', filter=Q(es_correcta=True)),
            )
            .order_by('pregunta_activa__pregunta__unidad')
        )

        mapa = []
        for d in datos:
            unidad = d['pregunta_activa__pregunta__unidad'] or '(sin unidad)'
            total  = d['total']
            pct    = round((d['correctas'] / total) * 100, 1) if total > 0 else 0
            nivel  = 'verde' if pct >= 70 else 'amarillo' if pct >= 50 else 'rojo'
            mapa.append({'tema': unidad, 'pct': pct, 'nivel': nivel, 'total_respuestas': total})

        return success_response(data=mapa)


class AlumnosEnRiesgoView(APIView):
    """
    GET /analytics/alumnos-riesgo/?seccion_id=N
    Lista alumnos con alertas de riesgo activas en la sección.
    """
    permission_classes = [IsApprovedDocente]

    def get(self, request):
        seccion_id = request.query_params.get('seccion_id')
        if not seccion_id:
            return error_response(message='seccion_id requerido.', status_code=400)

        alertas = AlertaRiesgo.objects.filter(
            seccion_id=seccion_id,
            seccion__asignatura__owner=request.user,
            activa=True,
        ).select_related('alumno').order_by('-nivel', '-created_at')

        data = [
            {
                'alumno_id':           a.alumno_id,
                'nickname':            a.alumno.nickname,
                'nivel':               a.nivel,
                'participacion_pct':   a.participacion_pct,
                'precision_pct':       a.precision_pct,
                'sesiones_analizadas': a.sesiones_analizadas,
                'desde':               a.created_at.strftime('%Y-%m-%d'),
            }
            for a in alertas
        ]
        return success_response(data=data)


class ParticipacionPorSesionView(APIView):
    """
    GET /analytics/participacion/?seccion_id=N
    Participación porcentual por sesión (últimas 10 sesiones).
    """
    permission_classes = [IsApprovedDocente]

    def get(self, request):
        seccion_id = request.query_params.get('seccion_id')
        if not seccion_id:
            return error_response(message='seccion_id requerido.', status_code=400)

        sesiones = Sesion.objects.filter(
            seccion_id=seccion_id, docente=request.user, estado='cerrada'
        ).order_by('-cerrada_en')[:10]

        from academic.models import Seccion as Sec
        try:
            total_alumnos = Sec.objects.get(pk=seccion_id).total_alumnos
        except Sec.DoesNotExist:
            total_alumnos = 1

        resultado = []
        for s in reversed(list(sesiones)):
            participantes = Respuesta.objects.filter(
                pregunta_activa__sesion=s
            ).values('alumno').distinct().count()

            pct = round((participantes / total_alumnos) * 100, 1) if total_alumnos > 0 else 0
            resultado.append({
                'sesion_id':    s.id,
                'titulo':       s.titulo,
                'fecha':        s.cerrada_en.strftime('%Y-%m-%d') if s.cerrada_en else None,
                'participacion': pct,
                'participantes': participantes,
                'total_alumnos': total_alumnos,
            })

        return success_response(data=resultado)


class NubeConceptosView(APIView):
    """
    GET /analytics/nube-conceptos/?seccion_id=N
    Conceptos más mencionados en reflexiones "punto confuso".
    """
    permission_classes = [IsApprovedDocente]

    def get(self, request):
        seccion_id = request.query_params.get('seccion_id')
        if not seccion_id:
            return error_response(message='seccion_id requerido.', status_code=400)

        conceptos = ConceptoConfuso.objects.filter(
            seccion_id=seccion_id, seccion__asignatura__owner=request.user
        ).order_by('-frecuencia')[:20]

        data = [{'concepto': c.concepto, 'frecuencia': c.frecuencia} for c in conceptos]
        return success_response(data=data)
