import aiohttp
import asyncio
import time
import uuid
from typing import Any, Dict

class YandexGPT:
    MAX_REQUESTS = 99  # Максимальное количество запросов перед обновлением куки

    def __init__(self):
        self.headers = {
            "Accept": "*/*",
            "Accept-Encoding": "gzip, deflate, br, zstd",
            "Accept-Language": "ru-RU,ru;q=0.9",
            "Cache-Control": "no-cache",
            "Content-Type": "application/json",
            "Device-Memory": "8",
            "Downlink": "5.4",
            "DPR": "1.5",
            "ECT": "4g",
            "Origin": "https://ya.ru",
            "Pragma": "no-cache",
            "Priority": "u=1, i",
            "Referer": ("https://ya.ru/search/?text=%D1%87%D1%82%D0%BE+%D0%B7%D0%B0+"
                       "%D1%80%D1%8B%D0%B1%D0%B0%D0%BB%D0%BA%D0%B0+%D1%81+"
                       "%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%82%D1%8E+%D1%83%D0%B4%D0%BE%D1%87%D0%BA%D0%B8&lr=47&search_source=yaru_desktop_common&search_domain=yaru"),
            "RTT": "100",
            "Sec-CH-UA": "\"Google Chrome\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"",
            "Sec-CH-UA-Arch": "\"x86\"",
            "Sec-CH-UA-Bitness": "\"64\"",
            "Sec-CH-UA-Full-Version": "\"129.0.6668.101\"",
            "Sec-CH-UA-Full-Version-List": (
                "\"Google Chrome\";v=\"129.0.6668.101\", "
                "\"Not=A?Brand\";v=\"8.0.0.0\", \"Chromium\";v=\"129.0.6668.101\""
            ),
            "Sec-CH-UA-Mobile": "?0",
            "Sec-CH-UA-Model": "\"\"",
            "Sec-CH-UA-Platform": "\"Windows\"",
            "Sec-CH-UA-Platform-Version": "\"15.0.0\"",
            "Sec-CH-UA-WoW64": "?0",
            "Sec-Fetch-Dest": "empty",
            "Sec-Fetch-Mode": "cors",
            "Sec-Fetch-Site": "same-origin",
            "User-Agent": (
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                "AppleWebKit/537.36 (KHTML, like Gecko) "
                "Chrome/129.0.0.0 Safari/537.36"
            ),
            "Viewport-Width": "736",
            "X-Requested-With": "XMLHttpRequest",
            "X-Retpath-Y": (
                "https://ya.ru/search/?text=%D1%87%D1%82%D0%BE+%D0%B7%D0%B0+"
                "%D1%80%D1%8B%D0%B1%D0%B0%D0%BB%D0%BA%D0%B0+%D1%81+"
                "%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%82%D1%8E+%D1%83%D0%B4%D0%BE%D1%87%D0%BA%D0%B8&lr=47&search_source=yaru_desktop_common&search_domain=yaru"
            )
        }
        self.request_count = 0
        self.session = None

    async def _initialize_session(self):
        """Инициализирует сессию и устанавливает куки."""
        self.session = aiohttp.ClientSession(headers=self.headers)
        try:
            async with self.session.get("https://ya.ru") as response:
                if response.status == 200:
                    print("Сессия инициализирована с куки.")
                else:
                    print(f"Не удалось инициализировать сессию: HTTP {response.status}")
        except aiohttp.ClientError as e:
            print(f"Ошибка инициализации сессии: {e}")

    async def _refresh_session(self):
        """Обновляет сессию, закрывая текущую и открывая новую."""
        if self.session:
            await self.session.close()
        self.session = aiohttp.ClientSession(headers=self.headers)
        try:
            async with self.session.get("https://ya.ru") as response:
                if response.status == 200:
                    print("Сессия обновлена и куки обновлены.")
                else:
                    print(f"Не удалось обновить сессию: HTTP {response.status}")
        except aiohttp.ClientError as e:
            print(f"Ошибка обновления сессии: {e}")
        self.request_count = 0

    async def send_prompt(self, prompt: str) -> str:
        """
        Отправляет промпт и получает ответ от Yandex GPT.
        Возвращает текст ответа или сообщение об ошибке.
        """
        if self.request_count >= self.MAX_REQUESTS:
            await self._refresh_session()
        elif self.session is None:
            await self._initialize_session()

        # Увеличиваем счетчик запросов
        self.request_count += 1

        # Создаем уникальный reqid
        timestamp = int(time.time() * 1_000_000)
        unique_id = uuid.uuid4().hex
        primary_reqid = f"{timestamp}-13515373250909564767-balancer-l7leveler-kubr-yp-sas-27-BAL"
        reqid = f"{timestamp}-16383473252948964099-balancer-l7leveler-kubr-yp-sas-27-BAL"
        
        url_send = (
            f"https://ya.ru/neuralsearch/api/send_to_dialog?"
            f"lr=11091&suggest_reqid=&primary_reqid={primary_reqid}&reqid={reqid}&from=button"
        )

        body_send = {
            "UserRequest": prompt
        }

        try:
            async with self.session.post(url_send, json=body_send) as response_send:
                if response_send.status != 200:
                    return f"текст ошибки: HTTP {response_send.status}"
                data_send = await response_send.json()
                response_message_id = data_send.get("ResponseMessageId")
                if not response_message_id:
                    return "текст ошибки: Отсутствует ResponseMessageId в ответе."
        except aiohttp.ClientError as e:
            return f"текст ошибки: {str(e)}"

        # Получение финального ответа
        url_fetch = (
            f"https://ya.ru/neuralsearch/api/get_fresh_message?"
            f"lr=11091&suggest_reqid=620775595168845935386354600584464&msid={response_message_id}&reqid={response_message_id}"
        )

        body_fetch = {
            "ResponseMessageId": response_message_id
        }

        try:
            while True:
                async with self.session.post(url_fetch, json=body_fetch) as response_fetch:
                    if response_fetch.status != 200:
                        return f"текст ошибки: HTTP {response_fetch.status}"
                    data_fetch = await response_fetch.json()
                    if data_fetch.get("IsFinalMarkdownText"):
                        return data_fetch.get("Text", "текст ошибки: Отсутствует текст в финальном ответе.")
                    await asyncio.sleep(1)  # Ожидание перед повторным запросом
        except aiohttp.ClientError as e:
            return f"текст ошибки: {str(e)}"

    async def close(self):
        """Закрывает сессию aiohttp."""
        if self.session:
            await self.session.close()

# Пример использования
async def main():
    gpt = YandexGPT()
    await gpt._initialize_session()  # Инициализируем сессию с куки

    try:
        response = await gpt.send_prompt("мой промпт")
        print("Финальный ответ:", response)
    finally:
        await gpt.close()

# Запуск примера
if __name__ == "__main__":
    asyncio.run(main()) верни чтобы куки и прочие данные были частью класса cls вместо self. так удобнее обращаться к коду из разных частей программы и сделай использование headers везде.