"""Ejemplo de integración de FaceID en un proyecto Django (kit v2).

El navegador envía la foto a ESTAS vistas (con sesión y CSRF); estas vistas
llaman a FaceID con la API key desde el servidor. La key nunca llega al HTML.

1. Copia faceid_client.py a tu app (p. ej. tu_app/faceid_client.py) y `pip install requests`.
2. settings.py:
       FACEID_URL = 'https://faceapi.epunemi.gob.ec'
       FACEID_API_KEY = os.environ['FACEID_API_KEY']      # o desde tu archivo de secretos
       DATA_UPLOAD_MAX_MEMORY_SIZE / FILE_UPLOAD_MAX_MEMORY_SIZE según tu política
3. urls.py:
       from tu_app import views_faceid
       path('faceid/enrolar/', views_faceid.enrolar),
       path('faceid/verificar/', views_faceid.verificar),
4. Plantilla: copia js/ejemplo.html + js/faceid-capture.js (ver README.md).
"""
import logging

from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.views.decorators.http import require_POST

from .faceid_client import FaceIDClient, FaceIDError

logger = logging.getLogger(__name__)

MAX_FOTO_BYTES = 5 * 1024 * 1024
TIPOS_PERMITIDOS = {'image/jpeg', 'image/png', 'image/webp'}

_faceid = None


def _cliente():
    """Un cliente por proceso (reutiliza la conexión HTTP)."""
    global _faceid
    if _faceid is None:
        _faceid = FaceIDClient(api_key=settings.FACEID_API_KEY, base_url=settings.FACEID_URL)
    return _faceid


def _foto(request):
    foto = request.FILES.get('foto')
    if not foto:
        raise FaceIDError('No se recibió la foto.')
    if foto.size > MAX_FOTO_BYTES:
        raise FaceIDError('La foto supera 5 MB.')
    if foto.content_type not in TIPOS_PERMITIDOS:
        raise FaceIDError('Formato de imagen no permitido.')
    return foto


def _error(e):
    # 403 = API key inválida o empresa desactivada: es un problema de configuración,
    # no del usuario. Regístralo y muestra un mensaje genérico.
    if e.status == 403:
        logger.error('FaceID rechazó la API key: %s', e.message)
        return JsonResponse({'isSuccess': False, 'message': 'El servicio de verificación no está disponible.'})
    return JsonResponse({'isSuccess': False, 'message': e.message})


@login_required
@require_POST
def enrolar(request):
    """Registra el rostro del usuario en sesión."""
    try:
        u = request.user
        _cliente().enrolar(
            _foto(request),
            cod_number=str(u.pk),            # identificador estable de TU sistema
            username=u.username, nombre=u.first_name, apellido=u.last_name, email=u.email,
            permite_actualizar=True,
        )
        return JsonResponse({'isSuccess': True, 'message': 'Rostro registrado correctamente.'})
    except FaceIDError as e:
        return _error(e)


@login_required
@require_POST
def verificar(request):
    """Verifica que quien está frente a la cámara es el usuario en sesión.

    La identidad sale de la sesión, NUNCA de lo que mande el navegador.
    La decisión (marcar asistencia, abrir examen…) se toma aquí, en el servidor.
    """
    try:
        r = _cliente().verificar(_foto(request), cod_number=str(request.user.pk))
        if r.get('is_same_person'):
            # Aquí registra tu evento: asistencia, inicio de examen, etc.
            return JsonResponse({'isSuccess': True, 'message': 'Identidad verificada.',
                                 'aData': {'is_same_person': True, 'similarity_score': r.get('similarity_score')}})
        return JsonResponse({'isSuccess': False, 'message': 'El rostro no coincide.'})
    except FaceIDError as e:
        if e.no_coincide:
            return JsonResponse({'isSuccess': False,
                                 'message': 'El rostro no coincide con el registrado. Mejora la luz y vuelve a intentar.'})
        return _error(e)
