from django.http import JsonResponse
from django.views.decorators.http import require_POST
from django.db import transaction
from django.core.exceptions import ObjectDoesNotExist
from accounts.mixins import ScannerAccessMixin
from core.models import Ticket, ScanLog

@require_POST
def verify_ticket_api(request, uuid):
    """
    API ultra-sécurisée appelée par la caméra JavaScript.
    Utilise 'select_for_update()' pour verrouiller le ticket pendant la transaction
    et empêcher la fraude si deux agents scannent en même temps.
    """
    # 1. Vérification de sécurité manuelle (car ce n'est pas une Class Based View)
    if not request.user.is_authenticated or not request.user.can_scan():
        return JsonResponse({'status': 'error', 'message': "Non autorisé"}, status=403)

    try:
        # transaction.atomic garantit que le verrouillage et les mises à jour se font en bloc
        with transaction.atomic():
            # select_for_update() bloque la ligne SQL jusqu'à la fin de la transaction
            ticket = Ticket.objects.select_for_update().get(code_unique=uuid)
            
            # Cas 1 : Ticket déjà annulé ou bloqué
            if ticket.statut == Ticket.Statut.ANNULE:
                ScanLog.objects.create(ticket=ticket, agent_scan=request.user, resultat=ScanLog.Resultat.INVALIDE)
                return JsonResponse({
                    'status': 'error',
                    'message': "Ce ticket est ANNULÉ.",
                    'client': ticket.client_nom
                })

            # Cas 2 : Ticket déjà utilisé (Quota atteint)
            if ticket.nb_scans_effectues >= ticket.nb_scans_autorises:
                # Mise à jour de sécurité du statut au cas où
                if ticket.statut != Ticket.Statut.SCANNE:
                    ticket.statut = Ticket.Statut.SCANNE
                    ticket.save()
                
                ScanLog.objects.create(ticket=ticket, agent_scan=request.user, resultat=ScanLog.Resultat.DEJA_UTILISE)
                return JsonResponse({
                    'status': 'warning',
                    'message': f"Ticket DÉJÀ UTILISÉ ({ticket.nb_scans_effectues}/{ticket.nb_scans_autorises}).",
                    'client': ticket.client_nom
                })

            # Cas 3 : Ticket Valide (Succès)
            ticket.nb_scans_effectues += 1
            if ticket.nb_scans_effectues >= ticket.nb_scans_autorises:
                ticket.statut = Ticket.Statut.SCANNE
            ticket.save()

            ScanLog.objects.create(ticket=ticket, agent_scan=request.user, resultat=ScanLog.Resultat.SUCCES)
            
            return JsonResponse({
                'status': 'success',
                'message': "ACCÈS AUTORISÉ",
                'client': ticket.client_nom,
                'type': ticket.type_ticket.nom,
                'event': ticket.type_ticket.evenement.nom
            })

    except ObjectDoesNotExist:
        # Le QR code ne correspond à aucun ticket de notre base de données
        return JsonResponse({'status': 'error', 'message': "Ticket Inconnu / Invalide."}, status=404)
    except Exception as e:
        # Erreur serveur imprévue
        return JsonResponse({'status': 'error', 'message': "Erreur système."}, status=500)