from gradio_client import Client
import random
import speech_recognition as sr
import pyttsx3
import keyboard
import time

# Создаем экземпляр клиента для вашего приложения Gradio
client = Client("yuntian-deng/ChatGPT4Turbo")

# Инициализируем список для хранения истории чата
chatbot_history = []

# Инициализируем синтезатор речи
engine = pyttsx3.init()

# Функция для распознавания речи с микрофона
def recognize_speech():
    recognizer = sr.Recognizer()
    with sr.Microphone() as source:
        print("\nГоворите... (нажмите Ctrl+C, чтобы выйти)")
        recognizer.adjust_for_ambient_noise(source)  # Настройка под уровень шума
        try:
            audio = recognizer.listen(source, timeout=10)  # Слушаем с максимальным ожиданием 10 секунд
            text = recognizer.recognize_google(audio, language="ru-RU")  # Распознаем с использованием Google API
            print(f"Вы сказали: {text}")
            return text
        except sr.UnknownValueError:
            print("Не удалось распознать речь. Попробуйте снова.")
            return None
        except sr.RequestError as e:
            print(f"Ошибка сервиса распознавания речи: {e}")
            return None
        except Exception as e:
            print(f"Произошла ошибка: {e}")
            return None

# Функция для озвучивания текста с возможностью прерывания
def speak_text(text):
    engine.say(text)
    engine.runAndWait()
    while engine.isBusy():
        if keyboard.is_pressed('q'):  # Прерывание по нажатию клавиши 'q'
            engine.stop()
            break
        time.sleep(0.1)

while True:
    try:
        # Предлагаем пользователю ввести текст или использовать голос
        print("\nВведите текст или оставьте строку пустой для голосового ввода:")
        user_input = input("Вы: ").strip()  # Получаем текстовый ввод

        if not user_input:  # Если пользователь ничего не ввел, переходим к голосовому вводу
            user_input = recognize_speech()
            if user_input is None:  # Если речь не распознана, продолжаем цикл
                continue

        # Добавляем текущий ввод в историю
        chatbot_history.append([user_input, None])

        # Устанавливаем параметр temperature на случайное значение
        temperature = random.uniform(0.7, 1.3)

        # Отправляем запрос к API /predict с заданными параметрами, включая историю чата
        result = client.predict(
            inputs=user_input,
            top_p=1,
            temperature=temperature,
            chat_counter=len(chatbot_history),
            chatbot=chatbot_history,
            api_name="/predict"
        )

        # Извлечение последнего ответа
        if isinstance(result, tuple) and len(result) > 0:
            conversation_history = result[0]
            if isinstance(conversation_history, list) and len(conversation_history) > 0:
                latest_interaction = conversation_history[-1]
                if isinstance(latest_interaction, list) and len(latest_interaction) >= 2:
                    response_text = latest_interaction[1]
                    print("Бот:", response_text)
                    # Обновляем последний элемент в истории, добавляя ответ
                    chatbot_history[-1][1] = response_text

                    # Озвучиваем ответ
                    speak_text(response_text)

    except KeyboardInterrupt:
        print("\nВыход из программы.")
        break
    except Exception as e:
        print(f"Возникла ошибка при вызове метода predict: {e}") добавь возможность при произнесении команды "Стоп" в момент озвучивания текста ответа - если произнесена команда "Стоп" закончи воспроизведение ответа и перейди к вводу нового запроса