from django.views.generic import TemplateView, DetailView, FormView
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.db.models import Count, Sum
from django.db import transaction
from django.contrib import messages

from accounts.mixins import AdminRequiredMixin
from core.models import Evenement, TypeTicket, Ticket
from core.services import generate_ticket_qr_code
from .forms import TicketCreateForm

class DashboardHomeView(AdminRequiredMixin, TemplateView):
    """Affiche la liste des événements actifs et les statistiques globales."""
    template_name = 'dashboard/home.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # On charge les événements avec leurs types de tickets pour éviter les requêtes N+1
        context['evenements'] = Evenement.objects.filter(est_actif=True).prefetch_related('types_tickets')
        
        # Calcul du Chiffre d'Affaires global et du volume de ventes
        tickets_valides = Ticket.objects.exclude(statut=Ticket.Statut.ANNULE)
        ca_total = tickets_valides.aggregate(total=Sum('type_ticket__prix'))['total'] or 0
        
        context['stats_globales'] = {
            'total_vendus': tickets_valides.count(),
            'chiffre_affaires': ca_total,
        }
        return context


class EvenementDetailView(AdminRequiredMixin, DetailView):
    """Affiche les statistiques d'un événement précis et les cartes pour générer les tickets."""
    model = Evenement
    template_name = 'dashboard/event_detail.html'
    context_object_name = 'evenement'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        evenement = self.get_object()
        
        # Statistiques locales à cet événement
        tickets_event = Ticket.objects.filter(type_ticket__evenement=evenement).exclude(statut=Ticket.Statut.ANNULE)
        ca_event = tickets_event.aggregate(total=Sum('type_ticket__prix'))['total'] or 0
        
        context['stats_evenement'] = {
            'tickets_vendus': tickets_event.count(),
            'chiffre_affaires': ca_event,
        }
        return context


class TicketCreateView(AdminRequiredMixin, FormView):
    """Traite la création du ticket, génère l'UUID et le QR Code de manière atomique."""
    template_name = 'dashboard/ticket_form.html'
    form_class = TicketCreateForm

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # On passe l'événement et le type de ticket au template pour affichage
        context['evenement'] = get_object_or_404(Evenement, pk=self.kwargs['evenement_id'])
        context['type_ticket'] = get_object_or_404(
            TypeTicket, 
            pk=self.kwargs['type_ticket_id'], 
            evenement_id=self.kwargs['evenement_id']
        )
        return context

    @transaction.atomic
    def form_valid(self, form):
        """Action déclenchée si le formulaire est valide."""
        type_ticket = get_object_or_404(TypeTicket, pk=self.kwargs['type_ticket_id'])
        
        # 1. Création de l'instance du ticket sans sauvegarder immédiatement
        ticket = form.save(commit=False)
        ticket.type_ticket = type_ticket
        
        # 2. Sauvegarde initiale pour générer l'UUID (nécessaire pour le QR Code)
        ticket.save() 
        
        # 3. Appel du service de génération du QR Code
        generate_ticket_qr_code(ticket)
        
        # 4. Sauvegarde finale avec l'image attachée
        ticket.save()
        
        messages.success(self.request, f"Ticket généré avec succès pour {ticket.client_nom}.")
        
        # Redirection dynamique vers l'aperçu du ticket généré
        self.success_url = reverse('dashboard:ticket_preview', kwargs={'uuid': ticket.code_unique})
        return super().form_valid(form)


class TicketPreviewView(AdminRequiredMixin, DetailView):
    """Affiche le ticket généré avec toutes ses informations visuelles pour exportation."""
    model = Ticket
    template_name = 'dashboard/ticket_preview.html'
    context_object_name = 'ticket'
    
    # On utilise l'UUID comme clé de recherche dans l'URL (sécurité anti-énumération)
    slug_field = 'code_unique'
    slug_url_kwarg = 'uuid'