"""
Module de définition du serveur WEB
"""
#liste des imports nécessaires
from flask import Flask, render_template, request, make_response, redirect
from numpy import asarray
from PIL import Image
from ultralytics import YOLO
from os.path import join

#création du serveur WEB, avec son nom
application_web = Flask('appli')

#définition de paramètres: ici l'emplacement de stockage des fichiers téléversés
application_web.config['UPLOAD_FOLDER'] = join('staticfiles','upload')

#route/url pour gérer le traitement
@application_web.route('/traiter_image', methods=['POST'])
def traiter():
    """
    Fonction pour récupérer l'image, et l'analyser
    En entrée: 
    - Rien
    Sortie:
    une réponse correspondant à une redirection vers la page d'accueil avec un message contenant les éléments anaylisés 
    par l'IA
    """
    #récupération de l'image envoyée par le formulaire
    image_yolo = request.files.get('image_yolo')
    #construction d'un chemin où stocker l'image
    chemin_image = join(application_web.config['UPLOAD_FOLDER'], image_yolo.filename)
    #stockage de l'image
    image_yolo.save(chemin_image)
    #chargement du modèle entrainé V8N
    modele = YOLO('yolov8n.pt')
    #création d'une image au format PIL, objet pour manipuler des images via python
    image_pil = Image.open(chemin_image)
    #transformation de l'image en matrice
    image_matrice = asarray(image_pil)
    #analyse de l'image par le modèle de prédiction
    retour_ia = modele.predict(image_matrice)
    #liste des objets ramenés par le modèle
    objets = []
    #pour chaque type trouvé
    for element in retour_ia:
        #pour chaque zone dans l'image du type trouvé
        for zone in element.boxes:
            #les coordonnées de la zone (angle haut gauche, bas droit)
            x1,y1, x2,y2 = zone.xyxy[0].tolist()
            #la classe du type
            class_id = zone.cls[0].item()
            #le nom "humain" pour cette classe
            nom_objet = element.names[class_id]
            #on ajoute uniquement le nom
            objets.append(nom_objet)

    #on créé le message
    message = f"Objets trouvés: {','.join(objets)}"
    #on l'envoie dans l'url (paramètre en GET)
    reponse = make_response(redirect(f'/?info={message}'))
    return reponse

#route/url pour la page d'accueil
@application_web.route('/', methods=['GET'])
def page_accueil():
    """
    Fonction générer le contenu HTML de la page d'accueil
    En entrée: 
    - Rien
    Sortie:
    le template HTML construit
    """
    #récupératin du nom de l'utilisateur
    nom = request.cookies.get('nom','')
    #y'a t il un argument "info" passé dans l'url ?
    message = request.args.get('info','')
    #je construis le template en passant les informations récoltées
    #et le renvoie
    return render_template('application.html', nom_uti = nom, le_message=message)

#route/url pour simuler la connexion d'un utilisateur
@application_web.route('/connecter', methods=['POST'])
def connecter_utilisateur():
    """
    Fonction pour générer un cookie contenant le nom de l'utilisateur passé dans le formulaire
    En entrée: 
    - Rien
    Sortie:
    une réponse correspondant à redirection vers la page d'accueil
    """
    #récupération du nom de l'utilisateur passé via le formulaire
    nom = request.form.get('nom_utilisateur')
    #création de la réponse
    reponse = make_response(redirect('/'))
    #ajout du cookie
    reponse.set_cookie('nom', nom)
    #renvoie de la reponse
    return reponse

#route/url pour simuler la deconnexion
@application_web.route('/deconnecter', methods=['GET'])
def tuer_connexion():
    """
    Fonction pour supprimer le cookie
    En entrée: 
    - Rien
    Sortie:
    une réponse correspondant à redirection vers la page d'accueil
    """
    #création de la réponse
    reponse = make_response(redirect('/'))
    #suppression du cookie (limite d'age à 0)
    reponse.set_cookie('nom', max_age=0)
    #renvoi de la réponse
    return reponse


if __name__ == "__main__": 
    #programme principal: on lance le serveur web !
    application_web.run()
