"""
Vistas — App Ratings
=====================
Crear valoración · Editar · Moderación · Respuesta doctora · API landing.
"""

import logging

from django.contrib import messages
from django.http import JsonResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.utils import timezone
from django.views.decorators.http import require_GET, require_POST

from apps.appointments.models import Cita
from apps.users.decorators import moderador_required, paciente_required

from .forms import RespuestaDoctorForm, ValoracionForm
from .models import PromedioGlobal, Valoracion

logger = logging.getLogger(__name__)


# ============================================================
# PACIENTE: Crear / Editar Valoración
# ============================================================
@paciente_required
def crear_valoracion(request, cita_id):
    """Formulario para que el paciente valore una cita completada."""
    cita = get_object_or_404(
        Cita,
        id=cita_id,
        paciente=request.user,
        estado=Cita.Estado.COMPLETADA,
    )

    # Verificar que no exista ya una valoración
    valoracion_existente = Valoracion.objects.filter(cita=cita).first()
    if valoracion_existente:
        if valoracion_existente.puede_editar:
            return redirect("ratings:editar_valoracion", valoracion_id=valoracion_existente.id)
        messages.info(request, "Já deixou uma avaliação para esta consulta.")
        return redirect("users:panel_paciente")

    if request.method == "POST":
        form = ValoracionForm(request.POST)
        if form.is_valid():
            valoracion = form.save(commit=False)
            valoracion.paciente = request.user
            valoracion.cita = cita
            valoracion.save()
            messages.success(
                request,
                "Obrigada pela sua avaliação! Ficará visível após aprovação.",
            )
            return redirect("users:panel_paciente")
    else:
        form = ValoracionForm()

    return render(request, "ratings/crear_valoracion.html", {
        "form": form,
        "cita": cita,
    })


@paciente_required
def editar_valoracion(request, valoracion_id):
    """Editar valoración dentro de las 48h."""
    valoracion = get_object_or_404(
        Valoracion,
        id=valoracion_id,
        paciente=request.user,
    )

    if not valoracion.puede_editar:
        messages.warning(request, "O prazo de 48 horas para editar expirou.")
        return redirect("users:panel_paciente")

    if request.method == "POST":
        form = ValoracionForm(request.POST, instance=valoracion)
        if form.is_valid():
            valoracion = form.save(commit=False)
            valoracion.estado = Valoracion.Estado.PENDIENTE  # Re-modera
            valoracion.save()
            messages.success(request, "Avaliação atualizada. Será revista novamente.")
            return redirect("users:panel_paciente")
    else:
        form = ValoracionForm(instance=valoracion)

    return render(request, "ratings/crear_valoracion.html", {
        "form": form,
        "cita": valoracion.cita,
        "editando": True,
    })


# ============================================================
# MIS VALORACIONES (paciente)
# ============================================================
@paciente_required
@require_GET
def mis_valoraciones(request):
    """Lista de valoraciones del paciente actual."""
    valoraciones = (
        Valoracion.objects
        .filter(paciente=request.user, is_active=True)
        .select_related("cita", "cita__servicio")
    )
    return render(request, "ratings/mis_valoraciones.html", {
        "valoraciones": valoraciones,
    })


# ============================================================
# MODERACIÓN (admin / doctora)
# ============================================================
@moderador_required
def panel_moderacion(request):
    """Panel de moderación de valoraciones."""

    estado_filtro = request.GET.get("estado", "pendiente")
    estrellas_filtro = request.GET.get("estrellas", "")

    qs = Valoracion.objects.filter(is_active=True).select_related(
        "paciente", "cita", "cita__servicio"
    )

    if estado_filtro in dict(Valoracion.Estado.choices):
        qs = qs.filter(estado=estado_filtro)

    if estrellas_filtro and estrellas_filtro.isdigit():
        qs = qs.filter(estrellas=int(estrellas_filtro))

    return render(request, "ratings/moderacion.html", {
        "valoraciones": qs,
        "estado_filtro": estado_filtro,
        "estrellas_filtro": estrellas_filtro,
        "estados": Valoracion.Estado.choices,
    })


@moderador_required
@require_POST
def aprobar_valoracion(request, valoracion_id):
    """Aprobar una valoración pendiente."""
    valoracion = get_object_or_404(Valoracion, id=valoracion_id)
    valoracion.estado = Valoracion.Estado.APROBADA
    valoracion.save()
    messages.success(request, "Avaliação aprovada.")
    return redirect("ratings:moderacion")


@moderador_required
@require_POST
def rechazar_valoracion(request, valoracion_id):
    """Rechazar una valoración pendiente."""
    valoracion = get_object_or_404(Valoracion, id=valoracion_id)
    valoracion.estado = Valoracion.Estado.RECHAZADA
    valoracion.save()
    messages.info(request, "Avaliação rejeitada.")
    return redirect("ratings:moderacion")


@moderador_required
@require_POST
def responder_valoracion(request, valoracion_id):
    """La doctora responde a una valoración aprobada."""
    valoracion = get_object_or_404(
        Valoracion,
        id=valoracion_id,
        estado=Valoracion.Estado.APROBADA,
    )

    if valoracion.respuesta_doctora:
        messages.info(request, "Já respondeu a esta avaliação.")
        return redirect("ratings:moderacion")

    form = RespuestaDoctorForm(request.POST)
    if form.is_valid():
        valoracion.respuesta_doctora = form.cleaned_data["respuesta"]
        valoracion.fecha_respuesta = timezone.now()
        valoracion.save()
        messages.success(request, "Resposta guardada.")
    return redirect("ratings:moderacion")


# ============================================================
# API PÚBLICA: Datos para el landing
# ============================================================
@require_GET
def api_testimonios(request):
    """Retorna testimonios aprobados y promedio global para el landing."""
    # Últimos 3 testimonios aprobados con comentario
    testimonios = (
        Valoracion.objects
        .filter(
            estado=Valoracion.Estado.APROBADA,
            is_active=True,
        )
        .exclude(comentario="")
        .select_related("paciente")
        .order_by("-created_at")[:3]
    )

    stats = PromedioGlobal.get_instance()

    data = {
        "testimonios": [
            {
                "nombre": f"{v.paciente.nombre} {v.paciente.apellido[:1]}.",
                "iniciales": v.iniciales_paciente,
                "estrellas": v.estrellas,
                "comentario": v.comentario,
                "respuesta_doctora": v.respuesta_doctora or None,
                "fecha": v.created_at.strftime("%d/%m/%Y"),
            }
            for v in testimonios
        ],
        "stats": {
            "promedio": float(stats.promedio),
            "total": stats.total,
            "distribucion": {
                "5": stats.estrellas_5,
                "4": stats.estrellas_4,
                "3": stats.estrellas_3,
                "2": stats.estrellas_2,
                "1": stats.estrellas_1,
            },
        },
    }
    return JsonResponse(data)
