from datetime import timedelta
import json
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect, render
from django.http import JsonResponse, HttpRequest
from django.forms import model_to_dict
from fonction_utilitaire import fonctions_utilitaire
from gestion_employe.models import Employe
from gestion_salle.forms import ReservationForm
from .models import Reservation


@login_required
def index(request: HttpRequest):

    try:
        employe = Employe.objects.get(user=request.user)
    except Employe.DoesNotExist:
        messages.error(request, "Profil employé introuvable.")
        return redirect('gestion_conges:conge')

    if request.method == "POST":
        form = ReservationForm(request.POST)

        if form.is_valid():
            date_debut = form.cleaned_data['date_debut']
            date_fin = form.cleaned_data['date_fin']
            salle = form.cleaned_data['salle']
            heure_debut = form.cleaned_data['heure_debut']
            heure_fin = form.cleaned_data['heure_fin']
            motif = form.cleaned_data['motif_reservation']
            besoin_zoom = form.cleaned_data['besoin_zoom']
            besoin_ordi = form.cleaned_data['besoin_ordi']

            if date_fin < date_debut:
                messages.error(request, "Date fin invalide.")
                return redirect('gestion_salle:reservation-salle')

            if heure_fin <= heure_debut:
                messages.error(request, "Heure invalide.")
                return redirect('gestion_salle:reservation-salle')
            
            if not request.user.first_name.strip() or not request.user.last_name.strip():
                messages.error(
                    request,
                    "Veuillez renseigner votre nom et prénom pour pouvoir faire une réservation."
                )
                return redirect('gestion_salle:reservation-salle')

            created = []
            current_date = date_debut

            while current_date <= date_fin:

                reservation = Reservation.objects.create(
                    employe=employe,
                    date_debut=current_date,
                    date_fin=current_date,
                    salle=salle,
                    heure_debut=heure_debut,
                    heure_fin=heure_fin,
                    besoin_zoom=besoin_zoom,
                    besoin_ordi=besoin_ordi,
                    motif_reservation=motif,
                    statut="en_attente"
                )

                created.append(reservation)
                current_date += timedelta(days=1)

            messages.success(request, "Réservation(s) créée(s) avec succès.")
            
            if fonctions_utilitaire.EMAIL_ASSISTANTE_DE_DIRECTION:
                fonctions_utilitaire.envoyer_mail(
                    sujet = "Reservation de salle",
                    message = f"""
Une nouvelle demande de réservation de la {dict(Reservation.TYPE_CHOICES).get(salle)} a été effectuée par {employe.user.first_name} {employe.user.last_name} du {form.cleaned_data.get('date_debut').strftime('%d/%m/%Y')} au {form.cleaned_data.get('date_fin').strftime('%d/%m/%Y')} pour motif "{motif}". 
Veuillez vous connecter à la plateforme pour plus de détails.""",
                    destinataires = fonctions_utilitaire.EMAIL_ASSISTANTE_DE_DIRECTION
                )
            return redirect('gestion_salle:reservation-salle')

    formulaire_reservation = ReservationForm()
    departement = employe.departement

    appartient_direction = request.user.groups.filter(name='direction').exists()

    liste_demande_reservation = Reservation.objects.filter(
        employe=employe,
        statut='en_attente'
    ).values_list('id', flat=True)

    context = {
        'formulaire_reservation': formulaire_reservation,
        'nb_reservation_attente': Reservation.objects.filter(statut='en_attente').count(),
        'appartient_au_departement_informatique': departement and departement.nom == "Systeme informatique",
        'appartient_direction': appartient_direction,
        'liste_demande_reservation': list(liste_demande_reservation),
    }

    return render(request, "gestion_salle/index.html", context)

def liste_reservation(request:HttpRequest):
    """Vue d'affichage des creneaux disponibles"""
    reservations = Reservation.objects.filter(statut = "validee")
    liste_reservation = []

    for reservation in reservations:
        color = None
        if reservation.statut == "en_attente":
            color = "#ffc107"
        elif reservation.statut == "validee":
            color = "#198754"
        else:
            color = "#dc3545"

        print(dict(Reservation.TYPE_CHOICES).get(reservation.salle))

        liste_reservation.append({ 
            "guid": reservation.pk, 
            "title": dict(Reservation.TYPE_CHOICES).get(reservation.salle),
            "date": reservation.date_debut, 
            "start": reservation.heure_debut, 
            "end": reservation.heure_fin, 
            "color": color,
        })
    return JsonResponse(liste_reservation, safe=False)

@login_required
def liste_reservation_attente(request):
    reservations = Reservation.objects.filter(statut="en_attente")
    liste_reservation = [
        {
            **model_to_dict(reservation),
            "employe": f"{reservation.employe.user.first_name} {reservation.employe.user.last_name}",
            "employe_id": reservation.employe.user.id,
            "salle": dict(Reservation.TYPE_CHOICES).get(reservation.salle),
            'statut': dict(Reservation.STATUT).get(reservation.statut),
        } for reservation in reservations
    ]

    return JsonResponse(liste_reservation, safe=False)

def detail_reservation(request:HttpRequest, reservation_id:int):
    
    reservation = Reservation.objects.get(id=reservation_id)
    employe = reservation.employe.user
    
    reservation_json = {
        
        'id_reservation': reservation_id,
        'employe': f"{employe.first_name} {employe.last_name}",
        'salle': reservation.salle,
        'statut': dict(Reservation.STATUT).get(reservation.statut),
        'date_evenement': reservation.date_debut.strftime('%Y-%m-%d'),
        'heure_debut': reservation.heure_debut.strftime('%H:%M'),
        'heure_fin': reservation.heure_fin.strftime('%H:%M'),
        'motif_reservation': reservation.motif_reservation,
        'besoin_zoom': reservation.besoin_zoom,
        'besoin_ordinateur': reservation.besoin_ordi,
        'lien_zoom': reservation.lien_zoom or '',
    }

    return JsonResponse(reservation_json, safe=True)

@login_required
def ajouter_lien_zoom(request:HttpRequest):
    """Vue de gestion de l'ajout du lien zoom"""
    if request.method == 'POST':
        reservation_id= request.POST['id_reservation']
        try:
            reservation =  Reservation.objects.get(id=reservation_id)
        except reservation.DoesNotExist:
            messages.error(request, "La resevertion selectionné n'existe pas.")
            return redirect("salle")
        
    if not (reservation.besoin_zoom or reservation.salle == "lien_zoom"):
        messages.error(request, "Cette réservation ne nécessite pas de lien Zoom.")
        return redirect('gestion_salle:reservation-salle')
    elif reservation.statut in ["annulee", "refusee"]:
        messages.error(request, "Le lien Zoom ne peut être ajouté pour les réservations annulée ou refusée.")
        return redirect('gestion_salle:reservation-salle')

    if request.method == "POST":
        lien = request.POST.get("lien_zoom")
        reservation.lien_zoom = lien
        reservation.statut = "validee"   
        reservation.save()
        messages.success(request, "Le lien Zoom a été ajouté et la réservation a été validée. ")
    return redirect('gestion_salle:reservation-salle')

@login_required
def annuler_reservation(request:HttpRequest):
    """Vue de gestion de l'annulation de la reservation"""
    if request.method == 'POST':
        reservation_id= request.POST['id_reservation']
        try:
            reservation =  Reservation.objects.get(id=reservation_id)
        except Reservation.DoesNotExist:
            messages.error(request, "La resevertion selectionné n'existe pas.")
            return redirect("salle")
        
        reservation.statut = 'annulee'
        reservation.save()
        messages.success(request, "Votre réservation a été annulée.")
    return redirect('gestion_salle:reservation-salle')

@login_required
def valider_reservation(request: HttpRequest):
    """Validation d'une réservation"""
    if request.method == 'POST':
        reservation_id = request.POST.get('id_reservation')

        try:
            reservation = Reservation.objects.get(id=reservation_id)
        except Reservation.DoesNotExist:
            messages.error(request, "La réservation sélectionnée n'existe pas.")
            return redirect("salle")

        reservation.statut = 'validee'
        reservation.save()

        fonctions_utilitaire.envoyer_mail(
            sujet = "Reservation de salle",
            message = f"""Bonjour {request.user.first_name} {request.user.last_name}, votre reservation de la salle {dict(Reservation.TYPE_CHOICES).get(reservation.salle)} du {reservation.date_debut.strftime('%d/%m/%Y')} au {reservation.date_fin.strftime('%d/%m/%Y')} pour motif "{reservation.motif_reservation}" a été validée. Veuillez vous connecter à la plateforme pour plus de détails.""",
            destinataires = [reservation.employe.user.email]
        )

    messages.success(request, f"La réservation de {request.user.first_name} {request.user.last_name} validée avec succès.")
    return redirect('gestion_salle:reservation-salle')

@login_required
def refuser_reservation(request: HttpRequest):
    """Refuser une réservation"""
    if request.method == 'POST':
        reservation_id = json.loads(request.body).get('id_reservation')

        try:
            reservation = Reservation.objects.get(id=reservation_id)
        except Reservation.DoesNotExist:
            messages.error(request, "La réservation n'existe pas.")
            return JsonResponse({"message": "Une erreur s'est produite lors de l'annulation de la reservation."})

        reservation.statut = 'refusee'
        reservation.save()

        fonctions_utilitaire.envoyer_mail(
            sujet = "Reservation de salle",
            message = f"""Bonjour {request.user.first_name} {request.user.last_name}, votre reservation de la salle {dict(Reservation.TYPE_CHOICES).get(reservation.salle)} du {reservation.date_debut.strftime('%d/%m/%Y')} au {reservation.date_fin.strftime('%d/%m/%Y')} pour motif "{reservation.motif_reservation}" a été refusée. Veuillez vous connecter à l'Assistante de Direction pour plus de détails.""",
            destinataires = [reservation.employe.user.email]
        )

        return JsonResponse({"message": "Réservation refusée avec succès."})