"""Views pour la gestion des véhicules."""

from pyexpat.errors import messages
from django.shortcuts import render, redirect
from django.http import JsonResponse

from authentification.models import Profile
from django.contrib.auth.models import Group
from django.contrib.auth.decorators import login_required
from . import forms
from . import models


@login_required(login_url="login")
def index(request):
    """Retournez la page d'accueil de la gestion des véhicules.

    Parameters
    ----------
    request : HttpRequest
        La requête HTTP reçue.

    Returns
    -------
    HttpResponse
        La réponse HTTP avec le rendu de la page d'accueil de la gestion des
        véhicules.

    """
    formulaire_enregistrer_vehicule = forms.EnregistrerVehicule()
    formulaire_demande_vehicule = forms.EnregistrerDemande()
    parc_vehicule = models.Vehicule.objects.all().order_by("-id")

    return render(
        request,
        "gestion_vehicule/index.html",
        {
            "formulaire_enregistrer_vehicule": formulaire_enregistrer_vehicule,
            "parc_vehicule": parc_vehicule,
            "formulaire_demande_vehicule": formulaire_demande_vehicule,
        },
    )


@login_required(login_url="login")
def enregistrer_voiture(request):
    """Enregistrez un nouveau véhicule.

    Parameters
    ----------
    request : HttpRequest
        La requête HTTP reçue.

    Returns
    -------
    HttpResponseRedirect
        Redirige vers la page d'accueil de la gestion des véhicules après
        l'enregistrement du véhicule.

    """
    if request.method == "POST":
        form_enregistrement = forms.EnregistrerVehicule(
            request.POST,
            request.FILES,
        )
        if form_enregistrement.is_valid:
            form_enregistrement.save()

        return redirect("gestion_vehicule:index")
    return None

@login_required(login_url="login")
def enregistrer_demande(request):
    """Enregistrez une nouvelle demande de véhicule.

    Parameters
    ----------
    request : HttpRequest
        La requête HTTP reçue.

    Returns
    -------
    JsonResponse
        Une réponse JSON indiquant le succès ou l'échec de l'enregistrement
        de la demande de véhicule.

    """
    if request.method == "POST":
        form_demande = forms.EnregistrerDemande(request.POST)
        if form_demande.is_valid():
            form = form_demande.save(commit=False)
            form.nom_passager = request.user.profile
            form.save()

            models.CarnetBord.objects.create(
                course=models.DemandeVehicule.objects.get(id=form.id)
            )

            return JsonResponse(
                {"success": True, "message": "Demande enregistrée avec succès"}
            )
        return JsonResponse(
            {
                "success": False,
                "message": (
                    "Une erreur s'est produit lors de "
                    "l'enregistrement de la demande"
                ),
            }
        )
    return None

@login_required(login_url="login")
def liste_demande(request):
    """Affichez la liste des demandes de véhicules.

    La liste des demandes affichées dépend du groupe de l'utilisateur connecté:
    - Si l'utilisateur appartient au groupe "Chauffeur", seules les demandes
        qui lui sont assignées sont affichées.
    - Sinon, toutes les demandes de véhicules sont affichées.

    Parameters
    ----------
    request : HttpRequest
        La requête HTTP reçue.

    Returns
    -------
    JsonResponse
        Une réponse JSON contenant la liste des demandes de véhicules.

    """
    liste_demande_vehicule = []

    if request.user.groups.filter(name="Chauffeur").exists():
        liste_demande_vehicule = models.DemandeVehicule.objects.filter(
            chauffeur__user_id=request.user.id
        )
    else:
        liste_demande_vehicule = models.DemandeVehicule.objects.all()

    demandes_en_cours = []
    parc_vehicule = [
        {"id": vehicule.id, "immatriculation": vehicule.immatriculation}
        for vehicule in models.Vehicule.objects.filter(disponible=True)
    ]
    chauffeur_group = Group.objects.get(name="Chauffeur")
    chauffeurs = [
        {
            "chauffeur_id": chauffeur.user.id,
            "chauffeur_name": (
                f"{chauffeur.user.first_name} {chauffeur.user.last_name}"
            ),
        }
        for chauffeur in Profile.objects.filter(user__groups=chauffeur_group)
    ]

    demandes_en_cours = [
        {
            "id_demande": demande.id,
            "nom_passager": (
                f"{demande.nom_passager.user.first_name} "
                f"{demande.nom_passager.user.last_name}"
            ),
            "lieu_depart": demande.lieu_depart,
            "date_heure_depart": demande.date_heure.strftime("%d/%m/%Y %H:%M"),
            "lieu_arrivee": demande.lieu_arrive,
            "validation": demande.validation,
            "vehicule": parc_vehicule,
            "chauffeurs": chauffeurs,
            "motif_refus": demande.motif_refus,
            "user_id": demande.nom_passager.user.id,
            "is_logisticien": (
                request.user.profile.departement
                .nom_departement == "Logistique"
            ),
            "is_chauffeur": (
                request.user.groups.filter(name="Chauffeur")
                .exists()
            ),
        }
        for demande in liste_demande_vehicule
    ]

    return JsonResponse(demandes_en_cours, safe=False)

@login_required(login_url="login")
def detail_course(request, id_demande):
    """Afficher les détails d'une demande de véhicule spécifique.

    Parameters
    ----------
    request : HttpRequest
        La requête HTTP reçue.
    id_demande : int
        L'identifiant de la demande de véhicule.

    Returns
    -------
    HttpResponse
        La réponse HTTP avec le rendu de la page de détails de la demande de
        véhicule.

    """
    la_demande = models.DemandeVehicule.objects.get(id=id_demande)
    vehicule = la_demande.vehicule

    details_course = models.CarnetBord.objects.get(course=la_demande)

    return render(
        request,
        "gestion_vehicule/detail_course.html",
        {
            "detail_demande": {
                "id": la_demande.id,
                "nom_passager": (
                    f"{la_demande.nom_passager.user.first_name} "
                    f"{la_demande.nom_passager.user.last_name}"
                ),
                "lieu_depart": la_demande.lieu_depart,
                "date_heure": la_demande.date_heure,
                "lieu_arrive": la_demande.lieu_arrive,
                "immatriculation": la_demande.vehicule.immatriculation,
                "id_vehicule": la_demande.vehicule.id,
                "details_course": details_course,
                "prise_carburant_formulaire": forms.PriseCarburant(
                    initial={"vehicule": vehicule.immatriculation}
                ),
            },
        },
    )

@login_required(login_url="login")
def statut_demande(request):
    """Mettre à jour le statut d'une demande de véhicule.

    Parameters
    ----------
    request : HttpRequest
        La requête HTTP reçue.
        request.id-demande : int
            L'identifiant de la demande de véhicule à mettre à jour.
        request.radioValider : str
            Le statut de validation de la demande
            ("Valider", "Refuser", ou autre).
        request.vehicule : int
            L'identifiant du véhicule assigné (si validée).
        request.chauffeur : int
            L'identifiant du chauffeur assigné (si validée).
        request.motif : str
            Le motif de refus (si refusée).
        request.course_termine : str
            Indique si la course est terminée ("on" si cochée).
        request.date_heure_retour : str
            La date et l'heure de retour de la course (si terminée).
        request.heure_course_termine : str
            L'heure de fin de la course (si terminée).

    Returns
    -------
    HttpResponseRedirect
        Redirige vers la page d'accueil de la gestion des véhicules après
        la mise à jour du statut de la demande.

    """
    if request.method == "POST":
        demande = models.DemandeVehicule.objects.get(
            id=request.POST["id-demande"]
        )

        if "radioValider" in request.POST:
            if request.POST["radioValider"] == "Valider":
                demande.validation = True
                demande.vehicule = models.Vehicule.objects.get(
                    id=request.POST["vehicule"]
                )
                demande.chauffeur = models.Profile.objects.get(
                    user_id=request.POST["chauffeur"]
                )
            elif request.POST["radioValider"] == "Refuser":
                demande.validation = False
                demande.motif_refus = request.POST["motif"]
            else:
                demande.validation = None

        if (
            "course_termine" in request.POST
            and "date_heure_retour" in request.POST
            and request.POST["course_termine"] == "on"
            and request.POST["date_heure_retour"] != ""
        ):
            demande.course_terminer = True
            demande.heure_course_termine = request.POST["date_heure_retour"]

        demande.save()

    return redirect("gestion_vehicule:index")

@login_required(login_url="login")
def detail_voiture(request, vehicule_id):
    """Affichez les détails d'un véhicule spécifique.

    Parameters
    ----------
    request : HttpRequest
        La requête HTTP reçue.
    vehicule_id : int
        L'identifiant du véhicule.

    Returns
    -------
    HttpResponse
        La réponse HTTP avec le rendu de la page de détails du véhicule.

    """
    vehicule = models.Vehicule.objects.get(id=vehicule_id)

    return render(
        request,
        "gestion_vehicule/detail_vehicule.html",
        {
            "vehicule": vehicule,
            "carnet_bord_formulaire": forms.CarnetBord(
                initial={"vehicule": vehicule.immatriculation}
            ),
        },
    )

@login_required(login_url="login")
def enregistrer_prise_carburant(request, course_id):
    """Enregistrez une prise de carburant pour une course spécifique.

    Parameters
    ----------
    request : HttpRequest
        La requête HTTP reçue.
    course_id : int
        L'identifiant de la course pour laquelle enregistrer la prise de
        carburant.

    Returns
    -------
    HttpResponseRedirect
        Redirige vers la page de détails de la course après l'enregistrement
        de la prise de carburant.

    """
    course = models.DemandeVehicule(id=course_id)
    if request.method == "POST":
        prise_carburant = forms.PriseCarburant(request.POST)
        if prise_carburant.is_valid():
            d = prise_carburant.save(commit=False)
            d.course = course
            d.save()

    return redirect("gestion_vehicule:detail-course", id_demande=course_id)

@login_required(login_url="login")
def carnet_carburant(request, vehicule_id):
    """Affichez le carnet de carburant d'un véhicule spécifique.

    Parameters
    ----------
    request : HttpRequest
        La requête HTTP reçue.

    vehicule_id : int
        L'identifiant du véhicule.

    Returns
    -------
    HttpResponse
        La réponse HTTP avec le rendu de la page du carnet de carburant
        du véhicule.

    """
    return render(
        request,
        "gestion_vehicule/carnet_carburant.html",
        {
            "id_vehicule": vehicule_id
        }
    )

def carnet_sortie_vehicule(request, vehicule_id):
    """Affichez le carnet de sortie d'un véhicule spécifique.

    Parameters
    ----------
    request : HttpRequest
        La requête HTTP reçue.

    vehicule_id : int
        L'identifiant du véhicule.

    Returns
    -------
    HttpResponse
        La réponse HTTP avec le rendu de la page du carnet de sortie
        du véhicule.

    """
    return render(
        request,
        "gestion_vehicule/carnet_sortie_vehicule.html",
        {"id_vehicule": vehicule_id},
    )

@login_required(login_url="login")
def filtre_carnet_carburant(request):
    """Filtrez les prises de carburant d'un véhicule pour un mois spécifique.

    Parameters
    ----------
    request : HttpRequest
        La requête HTTP reçue.
        request.id_vehicule : int
            L'identifiant du véhicule.
        request.mois : str
            Le mois au format "YYYY-MM".

    Returns
    -------
    JsonResponse
        Une réponse JSON contenant la liste des prises de carburant
        filtrées.

    """
    id_vehicule = request.GET["id_vehicule"]
    annee, mois = request.GET["mois"].split("-")

    prises_carburant = models.CarnetCarburant.objects.filter(
        course__vehicule=models.Vehicule.objects.get(id=id_vehicule),
        date__year=annee,
        date__month=mois,
    )

    mon_carnet = [
        {
            "date": p.date,
            "nom_station": p.nom_station,
            "type_carburant": p.type_carburant,
            "litre": p.litre,
            "prix": p.prix,
            "montant_total": p.litre * p.prix,
            "kilometrage": p.kilometrage,
            "observation": p.observation,
            "nom_chauffeur": (
                f"{p.course.chauffeur.user.first_name} "
                f"{p.course.chauffeur.user.last_name}"
            ),
        }
        for p in prises_carburant
    ]

    return JsonResponse(mon_carnet, safe=False)

def filtre_sortie_vehicule(request):
    """Filtrez les sorties d'un véhicule pour un mois spécifique.

    Parameters
    ----------
    request : HttpRequest
        La requête HTTP reçue.
        request.id_vehicule : int
            L'identifiant du véhicule.
        request.mois : str
            Le mois au format "YYYY-MM".

    Returns
    -------
    JsonResponse
        Une réponse JSON contenant la liste des sorties de véhicule
        filtrées.

    """
    id_vehicule = request.GET["id_vehicule"]
    annee, mois = request.GET["mois"].split("-")

    sortie_vehicule = models.CarnetBord.objects.filter(
        course__vehicule=models.Vehicule.objects.get(id=id_vehicule),
        heure_effectif_depart__year=annee,
        heure_effectif_depart__month=mois,
    )

    mes_sorties = [
        {
            "nom_passager": (
                f"{p.course.nom_passager.user.first_name} "
                f"{p.course.nom_passager.user.last_name}"
            ),
            "lieu_depart": p.course.lieu_depart,
            "heure_depart_prevu": p.course.date_heure,
            "heure_depart_effectif": p.heure_effectif_depart,
            "lieu_arrive": p.course.lieu_arrive,
            "heure_arrive": p.heure_arrive,
            "nom_chauffeur": (
                f"{p.course.chauffeur.user.first_name} "
                f"{p.course.chauffeur.user.last_name}"
            ),
        }
        for p in sortie_vehicule
    ]

    return JsonResponse(mes_sorties, safe=False)

@login_required(login_url="login")
def enregistrer_carnet_bord(request, vehicule_id):
    """Enregistrez ou mettez à jour le carnet de bord d'un véhicule.

    Parameters
    ----------
    request : HttpRequest
        La requête HTTP reçue.
        request.mois_concerne : str
            Le mois concerné au format "YYYY-MM".
        request.km_debut_mois : int
            Le kilométrage au début du mois.
        request.km_fin_mois : int
            Le kilométrage à la fin du mois.

    vehicule_id : int
        L'identifiant du véhicule.

    Returns
    -------
    HttpResponseRedirect
        Redirige vers la page de détails du véhicule après l'enregistrement
        ou la mise à jour du carnet de bord.

    """
    if request.method == "POST":
        annee, mois = request.POST["mois_concerne"].split("-")
        _, created = models.CarnetBord.objects.update_or_create(
            mois_concerne="-".join([annee, mois, "01"]),
            defaults={
                "km_debut_mois": request.POST["km_debut_mois"],
                "km_fin_mois": request.POST["km_fin_mois"],
                "vehicule": models.Vehicule.objects.get(id=vehicule_id),
            },
        )

    if created:
        messages.success(request, "Création effectuée avec succès.")
    else:
        messages.success(request, "Mise à jour effectuée avec succès.")

    return redirect(detail_voiture, vehicule_id)

@login_required(login_url="login")
def carnet_vehicule_information(_request, mois_concerne):
    """Récupérez les informations du carnet de bord pour un mois spécifique.

    Parameters
    ----------
    request : HttpRequest
        La requête HTTP reçue.
    mois_concerne : str
        Le mois concerné au format "YYYY-MM".

    Returns
    -------
    JsonResponse
        Une réponse JSON contenant les informations du carnet de bord
        pour le mois spécifié.

    """
    annee, mois = mois_concerne.split("-")
    try:
        carnet_bord = models.CarnetBord.objects.get(
            mois_concerne="-".join([annee, mois, "01"])
        )
    except models.CarnetBord.DoesNotExist:
        carnet_dict = {}
    else:
        carnet_dict = {
            "km_debut": carnet_bord.km_debut_mois,
            "km_fin": carnet_bord.km_fin_mois,
        }

    return JsonResponse(carnet_dict)

def enregistrer_information_course_depart(request, id_demande):
    """Enregistrez les informations de départ d'une course spécifique.

    Parameters
    ----------
    request : HttpRequest
        La requête HTTP reçue.
    id_demande : int
        L'identifiant de la demande de véhicule.

    Returns
    -------
    HttpResponseRedirect
        Redirige vers la page de détails de la course après l'enregistrement
        des informations de départ.

    """
    demande = models.DemandeVehicule.objects.get(id=id_demande)
    vehicule = models.Vehicule.objects.get(id=request.POST["id-vehicule"])
    course = models.CarnetBord.objects.get(course=demande)

    course.vehicule = vehicule
    course.course = demande
    course.heure_effectif_depart = request.POST["heure-depart"]
    course.km_depart = request.POST["kilometrage_depart"]
    course.save()

    return redirect("gestion_vehicule:detail-course", id_demande)

def enregistrer_information_course_arrive(request, id_demande):
    """Enregistrez les informations d'arrivée d'une course spécifique.

    Parameters
    ----------
    request : HttpRequest
        La requête HTTP reçue.
    id_demande : int
        L'identifiant de la demande de véhicule.

    Returns
    -------
    HttpResponseRedirect
        Redirige vers la page de détails de la course après l'enregistrement
        des informations d'arrivée.

    """
    demande = models.DemandeVehicule.objects.get(id=id_demande)
    vehicule = models.Vehicule.objects.get(id=demande.vehicule.id)

    course = models.CarnetBord.objects.get(course=demande)

    course.vehicule = vehicule
    course.course = demande
    course.heure_arrive = request.POST["heure-effectif-arrivee"]
    course.km_arrive = request.POST["kilometrage-arrivee"]
    course.course_termine = "course-terminer" in request.POST
    course.save()

    return redirect("gestion_vehicule:detail-course", id_demande)
