import socket
import vosk
import json
import yaml
from fuzzywuzzy import fuzz
import tts
from const import SYSTEM_PROMPT
from llm_models.mini_4o_model import ModelClient
from services.lamp_service import turn_on, turn_off
from services.pc_service import enter_sleep_mode
import time

HOST = '0.0.0.0'  # Слушаем на всех интерфейсах
PORT = 6543  # Порт, который вы используете

client = ModelClient()

VA_CMD_LIST = yaml.safe_load(
    open('commands.yaml', 'rt', encoding='utf8'),
)

WAKE_WORD = "соня"
LISTEN_DURATION = 10  # Время прослушивания в секундах


def recognize_cmd(cmd: str):
    rc = {'cmd': '', 'percent': 0}
    for c, v in VA_CMD_LIST.items():
        for x in v:
            vrt = fuzz.ratio(cmd, x)
            if vrt > rc['percent']:
                rc['cmd'] = c
                rc['percent'] = vrt
    return rc


def execute_cmd(cmd: str, voice: str):
    if cmd == 'enter_sleep_mode':
        tts.va_speak(enter_sleep_mode())
    elif cmd == 'lamp_on':
        tts.va_speak(turn_on())
    elif cmd == 'lamp_off':
        tts.va_speak(turn_off())


def main():
    # Инициализация модели Vosk
    model = vosk.Model("model_small")
    recognizer = vosk.KaldiRecognizer(model, 44100)

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((HOST, PORT))
    server_socket.listen(1)
    print("Сервер запущен, ожидаем подключения...")

    while True:
        conn, addr = server_socket.accept()
        print(f"Подключено к {addr}")

        while True:
            data = conn.recv(1024)
            if not data:
                break

            # Распознавание речи
            if recognizer.AcceptWaveform(data):
                result = recognizer.Result()
                recognized_text = json.loads(result)['text']
                if recognized_text:
                    print("Распознанный текст:", recognized_text)

                    # Проверка на "wake word"
                    if WAKE_WORD in recognized_text.lower():
                        print("Wake word распознано, активируем режим прослушивания команд.")
                        start_time = time.time()

                        # Режим прослушивания команд
                        while time.time() - start_time < LISTEN_DURATION:
                            data = conn.recv(1024)
                            if not data:
                                break

                            if recognizer.AcceptWaveform(data):
                                result = recognizer.Result()
                                recognized_text = json.loads(result)['text']
                                if recognized_text:
                                    print("Распознанный текст:", recognized_text)

                                    cmd = recognize_cmd(recognized_text)
                                    print(cmd)

                                    if len(cmd['cmd'].strip()) <= 0:
                                        pass
                                    elif cmd['percent'] < 70 or cmd['cmd'] not in VA_CMD_LIST.keys():
                                        response_generator = client.get_response(
                                            message=recognized_text,
                                            sys_prompt=SYSTEM_PROMPT
                                        )

                                        full_response = []
                                        last = ''

                                        for response in response_generator:
                                            part = response.replace(last, '')
                                            print(part, end='', flush=True)
                                            full_response.append(part)
                                            last = response

                                        print()

                                        complete_response = ''.join(full_response)
                                        tts.va_speak(complete_response)
                                        client.history.append((recognized_text, complete_response))
                                    else:
                                        execute_cmd(cmd['cmd'], recognized_text)

                    else:
                        # Обработка команд вне режима прослушивания
                        cmd = recognize_cmd(recognized_text)
                        print(cmd)

                        if len(cmd['cmd'].strip()) <= 0:
                            pass
                        elif cmd['percent'] < 70 or cmd['cmd'] not in VA_CMD_LIST.keys():
                            response_generator = client.get_response(
                                message=recognized_text,
                                sys_prompt=SYSTEM_PROMPT
                            )

                            full_response = []
                            last = ''

                            for response in response_generator:
                                part = response.replace(last, '')
                                print(part, end='', flush=True)
                                full_response.append(part)
                                last = response

                            print()

                            complete_response = ''.join(full_response)
                            tts.va_speak(complete_response)
                            client.history.append((recognized_text, complete_response))
                        else:
                            execute_cmd(cmd['cmd'], recognized_text)

        conn.close()
        print("Соединение закрыто, ожидаем нового подключения...")


if __name__ == "__main__":
    main()


команды должны выполняться только при активации прослушивания команд, которое действует 10 секунд с момента обнаружения активационной фразы