import asyncio
import json
import logging

from openai import AsyncOpenAI

from smeshariki.settings import Settings
from smeshariki.strings import BotStrings, all_bot_strings

logger = logging.getLogger(__name__)

settings = Settings()
openai = AsyncOpenAI(api_key=settings.openai_api)


async def ask(text: str) -> dict:
    system_prompt = get_system_prompt()

    answer = await send_request(system_prompt, text)
    result = json.loads(answer)

    assert isinstance(result, dict)
    return result


def get_system_prompt() -> str:
    bot_strings_list = all_bot_strings.ezhik, all_bot_strings.barash, all_bot_strings.losyash

    names = ', '.join(strings.name for strings in bot_strings_list)

    triggers = []
    for strings in bot_strings_list:
        triggers += strings.phrases.keys()

    json_example = '{' + ', '.join(f'"{trigger}": true' for trigger in triggers) + '}'

    return f"""
    You control multiple bots at once. Their names are: {names}.
    
    You will be given messages from a group chat. You must analyze users' actions.
    When they don't address to you directly, they are likely speaking to each other.
    
    Answer in exactly the same following JSON structure as in the example:
    
    {json_example}
    
    Skip the fields if they are false. If all fields are false, output {{"nothing": true}}
    """


async def send_request(system_prompt: str, text: str) -> str:
    response = await openai.chat.completions.create(
        model='gpt-4o-mini-2024-07-18',
        response_format={'type': 'json_object'},
        messages=[
            {'role': 'system', 'content': system_prompt},
            {'role': 'user', 'content': text}
        ]
    )
    return response.choices[0].message.content
