#!/usr/bin/env python

import tkinter as tk
import time
import httpx
import json
from pynput.keyboard import Controller, Key
from pynput.mouse import Controller as MouseController
import pyperclip

keyboard = Controller()
mouse = MouseController()

def phind_request(prompt):
    msg = f"Il tuo ruolo:Sei un assistente.\n{prompt}"

    data = {
         "additional_extension_context": "",
        "allow_magic_buttons": True,
        "is_vscode_extension": True,
        "message_history": [{"content": msg, "role": "user"}],
        "requested_model": "Phind-70B",
        "user_input": msg
    }

    headers = {
        "Content-Type": "application/json;charset=UTF-8",
        "User-Agent": "",
        "Accept": "*/*",
        "Accept-Encoding": "Identity"
    }
    
    with httpx.Client(timeout=60.0) as client:
      response = client.post("https://https.extension.phind.com/agent/", json=data, headers=headers)
      content = ""
      for line in response.iter_lines():
          if line.startswith("data:"):
              try:
                  json_data = json.loads(line[6:])
                  if "choices" in json_data and "delta" in json_data["choices"][0]:
                      delta = json_data["choices"][0]["delta"]
                      if "content" in delta:
                          content += delta["content"]
              except json.JSONDecodeError:
                  continue

      return content

def ollama_request(
    prompt: str,
    model: str = "deepseek-v3.1:671b-cloud",          # metti qui il modello che preferisci
    host: str = "http://127.0.0.1:11434",             # cambia se Ollama è altrove
    options: dict | None = None,                      # es: {"temperature": 0.2, "num_ctx": 8192}
    system: str | None = None                         # eventuale system prompt
) -> str:
    """
    Invia un prompt a Ollama usando /api/generate in streaming e
    ritorna il testo completo generato.
    Compatibile con i modelli 'cloud' caricati in Ollama (es. *-cloud).
    """
    url = f"{host.rstrip('/')}/api/generate"
    payload = {
        "model": model,
        "prompt": prompt,
        "stream": True
    }
    if options:
        payload["options"] = options
    if system:
        payload["system"] = system

    text = []
    try:
        # streaming della risposta riga per riga (JSON lines)
        with httpx.Client(timeout=None) as client:
            with client.stream("POST", url, json=payload) as r:
                r.raise_for_status()
                for line in r.iter_lines():
                    if not line:
                        continue
                    try:
                        obj = json.loads(line)
                    except json.JSONDecodeError:
                        continue
                    # Ogni chunk contiene la chiave "response"
                    if "response" in obj and obj["response"]:
                        text.append(obj["response"])
                    # Quando "done" è True lo stream è finito
                    if obj.get("done"):
                        break
    except httpx.HTTPError as e:
        return f"[ollama_request HTTPError] {e}"
    except Exception as e:
        return f"[ollama_request Error] {e}"

    return "".join(text)

def on_submit(entry):
    selected_text = pyperclip.paste()  # Recupera il testo dalla clipboard
    user_input = entry.get()

    # Concatenare il testo selezionato con quello inserito dall'utente
    if selected_text:
        full_input = selected_text + " " + user_input
    else:
        full_input = user_input
    
    #text = phind_request(full_input)  # Recupera il testo generato dall'AI
    text = ollama_request(full_input)  # Recupera il testo generato dall'AI locale
    root.destroy()  # Chiude la finestra di dialogo
    time.sleep(0.2)  # Attende un attimo per assicurarsi che la finestra corrente sia attiva
    type_text(text)  # Simula l'incollaggio del testo

def type_text(text):
    pyperclip.copy(text)  # Copia il testo nella clipboard
    with keyboard.pressed(Key.ctrl):  # Simula Ctrl + V per incollare
        keyboard.press('v')
        keyboard.release('v')
    time.sleep(0.2)
    pyperclip.copy("")
    
def update_entry_size(event):
    entry.config(width=len(entry.get()) + 1)  # Espande il campo di testo man mano che scrivi


# Forza la copia del testo selezionato senza disturbare l'utente
with keyboard.pressed(Key.ctrl):
    keyboard.press('c')
    keyboard.release('c')
    
    time.sleep(0.1)  # Attende un attimo per copiare il testo

# Crea la finestra di dialogo
root = tk.Tk()
root.attributes('-topmost', True)  # Porta la finestra in primo piano
root.title("ideaAI")

# Posiziona la finestra dove si trova il cursore
cursor_x, cursor_y = mouse.position  # Usa pynput per ottenere la posizione del cursore
root.geometry(f'+{cursor_x}+{cursor_y}')

# Aggiunge un campo di testo
entry = tk.Entry(root, width=1)  # Imposta larghezza minima
entry.pack()

# Imposta il focus sul campo di testo e porta la finestra in primo piano
entry.focus()

# Aggiunge l'evento per aggiornare la dimensione del campo di testo mentre si scrive
entry.bind('<KeyRelease>', update_entry_size)

# Associa il tasto "Invio" alla funzione on_submit
entry.bind('<Return>', lambda event: on_submit(entry))

# Mostra la finestra di dialogo
root.mainloop()

