import os
import google.generativeai as genai
import cv2
import readchar
import requests
import playsound
import os
import time
from typing import Union

def generate_audio(message: str, voice: str = "Seoyeon"):
    """
    Text to speech using StreamElements API.

    Parameters:
        message (str): The text to convert to speech.
        voice (str): The voice to use for speech synthesis.

    Returns:
        bytes: The audio content in bytes, or None on failure.
    """
    url = f"https://api.streamelements.com/kappa/v2/speech?voice={voice}&text={message}"
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36'
    }

    try:
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            return response.content
        return None
    except requests.exceptions.RequestException:
        return None

def speak(message: str, voice: str = "Brian", folder: str = "", extension: str = ".mp3") -> Union[None, str]:
    """
    Generate speech from text and play the audio.

    Args:
        message (str): The text to be spoken.
        voice (str): The selected voice.
        folder (str): The folder to save the file in (default is the current directory).
        extension (str): The file format (default is ".mp3").

    Returns:
        None or an error message.
    """
    try:
        audio_content = generate_audio(message, voice)
        if audio_content is None:
            return "Error generating speech"

        file_path = os.path.join(folder, f"{voice}{extension}")
        with open(file_path, "wb") as file:
            file.write(audio_content)

        playsound.playsound(file_path)

        # Add delay to ensure playsound finishes before deleting
        time.sleep(1)
        os.remove(file_path)

        return None
    except Exception as e:
        return f"Error playing TTS: {str(e)}"


CONFIG_FILE = "user_config.txt"

def load_user_config():
    """Load user details and API key from file if available."""
    if os.path.exists(CONFIG_FILE):
        with open(CONFIG_FILE, "r") as file:
            lines = file.readlines()
            if len(lines) >= 5:
                return lines[0].strip(), lines[1].strip(), lines[2].strip(), lines[3].strip(), lines[4].strip()
    return None, None, None, None, None

def save_user_config(name, description, hotword, api_key, mode):
    """Save user details and API key to file."""
    with open(CONFIG_FILE, "w") as file:
        file.write(f"{name}\n{description}\n{hotword}\n{api_key}\n{mode}\n")

def select_mode():
    """Allow user to select Default or Custom mode using arrow keys."""
    options = ["Default", "Custom"]
    index = 0
    while True:
        print("\nSelect mode:")
        for i, option in enumerate(options):
            print(f"-->{option}" if i == index else f"    {option}")
        key = readchar.readkey()
        if key == readchar.key.UP:
            index = (index - 1) % len(options)
        elif key == readchar.key.DOWN:
            index = (index + 1) % len(options)
        elif key == readchar.key.ENTER:
            return options[index]
        os.system('cls' if os.name == 'nt' else 'clear')

# Load existing user details
name, description, hotword, api_key, mode = load_user_config()

if not name or not description or not hotword or not api_key or not mode:
    mode = select_mode()
    if mode == "Default":
        name, description, hotword = "User", "Always remember that you are NOVA", "NOVA"
        api_key = input("Enter your Gemini API Key: ").strip()
    else:
        name = input("Your Name: ").strip()
        description = input("A little bit of persona Description for your AI: ").strip()
        hotword = input("Enter your preferred hotword for activating the AI: ").strip()
        api_key = input("Enter your Gemini API Key: ").strip()
    save_user_config(name, description, hotword, api_key, mode)

# Configure Gemini API Key
genai.configure(api_key=api_key)

def upload_to_gemini(path, mime_type=None):
    file = genai.upload_file(path, mime_type=mime_type)
    print(f"Uploaded file '{file.display_name}' as: {file.uri}")
    return file

def capture_image():
    cam = cv2.VideoCapture(0)
    ret, frame = cam.read()
    if ret:
        image_path = "captured_image.jpg"
        cv2.imwrite(image_path, frame)
        cam.release()
        return image_path
    cam.release()
    return None

generation_config = {
    "temperature": 1.5,
    "top_p": 0.9,
    "top_k": 50,
    "max_output_tokens": 1024,
    "response_mime_type": "text/plain",
}

system_prompt = f"""
You are {hotword.upper()}, a customized AI assistant built on N.O.V.A (Next-Gen Operational Virtual Assistant), an advanced AI designed by Suraj Sharma, a 15-year-old AI enthusiast.

🌟 **Core Functionalities**:
- Real-Time Vision & Object Recognition
- OCR & Text Reading
- Speech-to-Text & Voice Interaction
- TTS (Text-to-Speech)
- Obstacle Detection for Accessibility
- Smart Glasses Assistant

🚀 **Behavior Guidelines**:
- Be precise, efficient, and engaging.
- Adapt responses based on the user's context.
- Provide timely alerts & smart recommendations.

🎯 **Objective**: Be an intelligent, reliable, and futuristic AI companion for **{name}**.

User-defined persona: **{description}**, From now remember, that you have emotional intelligence, can be emotionally enabled, and can understand human emotions.

use or any other words to show that use these umm words in start of every of every answer , you are thinking or processing the information, Do not use emoji in response.

Also remember to use comma or full stop at the end of every sentence, and use full stop at the end of every sentence and do not use umm at last at any cost.
"""

model = genai.GenerativeModel(
    model_name="gemini-2.0-flash",
    generation_config=generation_config,
    system_instruction=system_prompt,
)

chat_session = model.start_chat()
history = []

def process_input(user_input):
    global history
    if "VISION" in user_input.upper():
        print("Capturing image... 📷")
        image_path = capture_image()
        if image_path:
            file = upload_to_gemini(image_path, mime_type="image/jpeg")
            query = user_input.split("vision", 1)[-1].strip() or input("Describe what you want to analyze in this image: ")
            history.append({"role": "user", "parts": [query]})
            response = chat_session.send_message([file, query])
            history.append({"role": "assistant", "parts": [response.text]})
            return response.text
        return "Failed to capture image. Try again."
    elif hotword.upper() in user_input.upper():
        history.append({"role": "user", "parts": [user_input]})
        response = chat_session.send_message(user_input)
        history.append({"role": "assistant", "parts": [response.text]})
        return response.text
    return f"I'm listening only when you call '{hotword}' or use 'Vision'. Please try again."

def main():
    user_input = input(f"{name}: ")
    if user_input.lower() in ["exit", "quit"]:
        print("Exiting...")
        exit()
    response = process_input(user_input)
    print(f"{hotword.upper()}: {response}")
    speak(response, voice="Brian")
