# Philippe JONIN
# Octobre 2023

import openai
import tkinter as tk
from tkinter import scrolledtext


def ask_question():
    """Fonction pour envoyer la question et afficher la réponse"""

    user_input = entry.get("1.0", tk.END).strip()
    if user_input:
        # Ajouter la requête de l'utilisateur à l'historique des messages
        messages.append({"role": "user",
                         "content": user_input})

        # Appel à l'API OpenAI avec l'historique des messages
        completion = client.chat.completions.create(
            model="gpt-4-1106-preview",
            messages=messages
        )

        # Récupération de la réponse de l'API
        response_content = completion.choices[0].message.content

        # Mise à jour de l'historique de la conversation dans la
        # fenêtre graphique
        conversation_history.config(state=tk.NORMAL)
        conversation_pos = conversation_history.index(tk.INSERT)
        conversation_history.insert(tk.END, f"Vous : {user_input}\n")
        conversation_history.tag_add("locuteur",
                                     conversation_pos,
                                     str(float(conversation_pos) + 0.6))
        conversation_pos = conversation_history.index(tk.INSERT)
        conversation_history.insert(tk.END, f"Assistant : {response_content}\n\n")
        conversation_history.tag_add("locuteur",
                                     conversation_pos,
                                     str(float(conversation_pos) + 0.11))
        conversation_history.yview(tk.END)
        conversation_history.config(state=tk.DISABLED)

        # Ajouter la réponse de l'assistant à l'historique
        messages.append({"role": "assistant",
                         "content": response_content})

        # Nettoyer la zone de saisie
        entry.delete("1.0", tk.END)


def new_conversation():
    """Fonction pour démarrer une nouvelle conversation"""
    
    global messages

    # Réinitialisation de l'historique des messages
    messages = [{"role": "system",
                 "content": system_message_entry.get("1.0", tk.END).strip()}]

    # Effacement de l'historique de la conversation dans la fenêtre graphique
    conversation_history.config(state=tk.NORMAL)
    conversation_history.delete('1.0', tk.END)
    conversation_history.config(state=tk.DISABLED)


def update_system_message():
    """Fonction pour mettre à jour le message du système"""

    messages[0]["content"] = system_message_entry.get("1.0", tk.END).strip()
    system_message_label.config(text="Message du système mis à jour.")


def quit_application():
    """Fonction pour fermer l'application"""
    root.destroy()


# Clé d'accès située dans un autre fichier
with open("ma_cle_openai.txt") as fh:
    ma_cle = fh.read().strip()

# Création du client OpenAI
client = openai.OpenAI(api_key=ma_cle)

# Initialisation de l'historique des messages avec le message du système
messages = [
    {"role": "system",
     "content": "Tu es un assistant développeur informatique."}
]

# Création de la fenêtre principale
root = tk.Tk()
root.title("Assistant de conversation GPT-4")

# Création de la zone de texte pour l'historique de la conversation
# avec une couleur de fond différente
conversation_history = scrolledtext.ScrolledText(root,
                                                 state=tk.DISABLED,
                                                 height=20,
                                                 wrap=tk.WORD,
                                                 bg="light grey")
conversation_history.tag_config("locuteur", foreground="red")
conversation_history.pack(padx=10,
                          pady=10,
                          fill=tk.BOTH,
                          expand=True)

# Zone de saisie pour le message du système avec une couleur de fond différente
system_message_label = tk.Label(root, text="Rôle attribué à l'assistant ")
system_message_label.pack(padx=10,
                          pady=(0, 5))
system_message_entry = scrolledtext.ScrolledText(root,
                                                 height=3,
                                                 wrap=tk.WORD,
                                                 bg="light blue")
system_message_entry.pack(padx=10,
                          pady=(0, 10),
                          fill=tk.X)
system_message_entry.insert(tk.END, messages[0]["content"])

# Bouton pour mettre à jour le message du système
update_system_message_button = tk.Button(root,
                                         text="Mettre à jour le message du système",
                                         command=update_system_message)
update_system_message_button.pack(padx=10, pady=(0, 5))

# Création de la zone de saisie pour la question avec une couleur
# de fond différente
entry_label = tk.Label(root, text="Posez votre question :")
entry_label.pack(padx=10,
                 pady=(0, 5))
entry = scrolledtext.ScrolledText(root,
                                  height=3,
                                  wrap=tk.WORD,
                                  bg="light yellow")
entry.pack(padx=10,
           pady=(0, 10),
           fill=tk.X)

# Création du bouton d'envoi
send_button = tk.Button(root,
                        text="Envoyer",
                        command=ask_question)
send_button.pack(padx=10,
                 pady=(0, 5),
                 side=tk.LEFT)

# Création du bouton de nouvelle conversation
new_button = tk.Button(root,
                       text="Nouvelle conversation",
                       command=new_conversation)
new_button.pack(padx=10,
                pady=(0, 5),
                side=tk.LEFT)

# Création du bouton de sortie
exit_button = tk.Button(root,
                        text="Quitter",
                        command=quit_application)
exit_button.pack(padx=10,
                 pady=(0, 5),
                 side=tk.RIGHT)

# Démarrage de la boucle principale événementielle de l'interface
# graphique
root.mainloop()
