"""
Модуль для генерации описаний маршрутов и ответов на вопросы пользователей.
Использует Gemini-2.5-flash API через requests библиотеку.
"""

import json
import requests
from typing import List, Dict, Optional


class RouteDescriber:
    """
    Класс для работы с описанием маршрутов и ответами на вопросы пользователей.
    """

    def __init__(self):
        """
        Инициализация с API ключом Gemini.

        Args:
            api_key: API ключ для доступа к Gemini API
        """
        self.api_key = 'AIzaSyBXGBGH5NDY8L_jVmq2zb4i8xYEV2qN-48'
        self.base_url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent"
        self.conversation_history = []
        self.route_points = []
        self.route_description = ""
        self.parser_chat_context = ""

    def _call_gemini(self, prompt: str, system_instruction: Optional[str] = None) -> str:
        """
        Выполняет запрос к Gemini API.

        Args:
            prompt: Текст промпта
            system_instruction: Системная инструкция для модели

        Returns:
            Ответ модели
        """
        url = f"{self.base_url}?key={self.api_key}"

        headers = {
            "Content-Type": "application/json"
        }

        # Формируем тело запроса
        contents = []

        # Добавляем историю разговора
        for msg in self.conversation_history:
            contents.append(msg)

        # Добавляем текущий промпт
        contents.append({
            "role": "user",
            "parts": [{"text": prompt}]
        })

        payload = {
            "contents": contents
        }

        # Добавляем системную инструкцию если есть
        if system_instruction:
            payload["system_instruction"] = {
                "parts": [{"text": system_instruction}]
            }

        try:
            response = requests.post(url, headers=headers, json=payload, timeout=30)
            response.raise_for_status()

            result = response.json()

            # Извлекаем текст ответа
            if "candidates" in result and len(result["candidates"]) > 0:
                candidate = result["candidates"][0]
                if "content" in candidate and "parts" in candidate["content"]:
                    answer = candidate["content"]["parts"][0]["text"]

                    # Сохраняем в историю
                    self.conversation_history.append({
                        "role": "user",
                        "parts": [{"text": prompt}]
                    })
                    self.conversation_history.append({
                        "role": "model",
                        "parts": [{"text": answer}]
                    })

                    return answer

            return "Ошибка при получении ответа"

        except requests.exceptions.RequestException as e:
            return f"Ошибка запроса: {str(e)}"

    def generate_route_description(self, route_points: List[Dict],
                                   parser_chat_history: Optional[List[Dict]] = None) -> str:
        """
        Генерирует описание маршрута на основе точек.

        Args:
            route_points: Список точек маршрута с полями 'name' и 'description'
            parser_chat_history: История чата с парсером в формате [{"role": "user"/"model", "text": "..."}]

        Returns:
            Описание маршрута (1-2 предложения на точку)
        """
        self.route_points = route_points
        self.conversation_history = []  # Очищаем историю для нового маршрута

        # Обрабатываем историю чата с парсером
        if parser_chat_history:
            parser_messages = []
            for msg in parser_chat_history:
                role = msg.get('role', 'user')
                text = msg.get('text', '')
                parser_messages.append(f"{role.upper()}: {text}")
            self.parser_chat_context = "\n".join(parser_messages)
        else:
            self.parser_chat_context = ""

        # Формируем промпт
        points_info = []
        for i, point in enumerate(route_points, 1):
            name = point.get('name', f'Точка {i}')
            description = point.get('description', '')
            points_info.append(f"{i}. {name}\nОписание: {description}")

        prompt = f"""Создай краткое описание маршрута из {len(route_points)} точек. 
Для каждой точки напиши 1-2 предложения, которые заинтересуют посетителя.
Используй только информацию из описаний точек.

Точки маршрута:
{chr(10).join(points_info)}

Формат ответа:
1. [Название точки]: [1-2 предложения описания]
2. [Название точки]: [1-2 предложения описания]
..."""

        # Добавляем контекст парсера если есть
        if self.parser_chat_context:
            prompt = f"""История запроса пользователя:
{self.parser_chat_context}

{prompt}"""

        system_instruction = """Ты — помощник для описания туристических маршрутов.
Твоя задача — создавать краткие, привлекательные описания точек маршрута (1-2 предложения на точку).
Используй только информацию, представленную в описаниях точек.
Пиши на русском языке."""

        description = self._call_gemini(prompt, system_instruction)
        self.route_description = description
        return description

    def answer_question(self, question: str) -> str:
        """
        Отвечает на вопрос пользователя о точках маршрута.
        Видит всю историю вопросов и ответов, а также описание маршрута.

        Args:
            question: Вопрос пользователя

        Returns:
            Ответ на основе информации из описаний точек
        """
        # Формируем контекст с информацией о точках
        points_context = []
        for i, point in enumerate(self.route_points, 1):
            name = point.get('name', f'Точка {i}')
            description = point.get('description', 'Нет описания')
            points_context.append(f"{i}. {name}: {description}")

        context = "\n\n".join(points_context)

        # Добавляем информацию о парсере если есть
        parser_info = ""
        if self.parser_chat_context:
            parser_info = f"""

ИСТОРИЯ ЗАПРОСА ПОЛЬЗОВАТЕЛЯ (для контекста):
{self.parser_chat_context}
"""

        # Добавляем описание маршрута если оно было сгенерировано
        route_desc_info = ""
        if self.route_description:
            route_desc_info = f"""

ОПИСАНИЕ МАРШРУТА, КОТОРОЕ БЫЛО ПОКАЗАНО ПОЛЬЗОВАТЕЛЮ:
{self.route_description}
"""

        system_instruction = f"""Ты — помощник по туристическому маршруту. 
{parser_info}{route_desc_info}

ДОСТУПНАЯ ИНФОРМАЦИЯ О ТОЧКАХ МАРШРУТА:
{context}

СТРОГИЕ ПРАВИЛА:
1. Отвечай ТОЛЬКО на вопросы о точках маршрута
2. Используй ТОЛЬКО информацию из описаний точек выше
3. Если в описаниях нет информации для ответа на вопрос, вежливо уходи от ответа фразами вида "Вы узнаете ответ, когда посетите это место", адаптируй под контекст.
4. НЕ давай рекомендаций и советов
5. НЕ отвечай на вопросы, не связанные с маршрутом. В таких случаях отвечай: "Я могу ответить только на вопросы о точках вашего маршрута"
6. НЕ придумывай информацию, которой нет в описаниях
7. Отвечай кратко и по существу на русском языке
8. Ты видишь всю историю разговора, поэтому можешь отвечать на уточняющие вопросы"""

        answer = self._call_gemini(question, system_instruction)
        return answer

    def reset_conversation(self):
        """Очищает историю разговора."""
        self.conversation_history = []
        self.route_points = []
        self.route_description = ""
        self.parser_chat_context = ""


# Пример использования
if __name__ == "__main__":
    # Инициализация (замените на ваш API ключ)
    API_KEY = "YOUR_GEMINI_API_KEY"
    describer = RouteDescriber(API_KEY)

    # Пример истории чата с парсером
    parser_chat = [
        {"role": "user", "text": "Хочу погулять по центру Москвы, интересует история и искусство"},
        {"role": "model", "text": "Понял, вы хотите прогулку по историческому центру с посещением музеев. Сколько времени у вас есть?"},
        {"role": "user", "text": "Часа 3-4"},
        {"role": "model", "text": "Отлично, я составил маршрут из 3 точек по центру Москвы с историческими местами и музеем искусства."}
    ]

    # Пример данных маршрута
    route_points = [
        {
            "name": "Красная площадь",
            "description": "Главная площадь Москвы, окружённая историческими зданиями. Здесь находятся Кремль, собор Василия Блаженного и Мавзолей Ленина. Площадь была основана в конце XV века."
        },
        {
            "name": "Парк Горького",
            "description": "Один из самых известных парков Москвы, расположенный на берегу Москвы-реки. Здесь есть зоны для отдыха, спортивные площадки, прокат велосипедов. Парк был открыт в 1928 году."
        },
        {
            "name": "Третьяковская галерея",
            "description": "Художественный музей с крупнейшей коллекцией русского искусства. В экспозиции представлены работы от древнерусских икон до картин XX века. Основана купцом Павлом Третьяковым."
        }
    ]

    # Генерация описания маршрута с историей парсера
    print("=== ОПИСАНИЕ МАРШРУТА ===")
    description = describer.generate_route_description(route_points, parser_chat)
    print(description)
    print()

    # Примеры вопросов (теперь с контекстом истории)
    print("=== ДИАЛОГ С ПОЛЬЗОВАТЕЛЕМ ===")

    questions = [
        "Когда был основан Парк Горького?",
        "А что там можно делать?",  # Уточняющий вопрос о предыдущей теме
        "Какие картины есть в Третьяковской галерее?",
        "Сколько стоит билет?",  # Без контекста, но система поймет что это про музей
        "Расскажи про Кремль",
        "Что посоветуешь взять с собой?",  # Попытка получить рекомендацию
        "Как погода сегодня?"  # Нерелевантный вопрос
    ]

    for q in questions:
        print(f"\n👤 Пользователь: {q}")
        answer = describer.answer_question(q)
        print(f"🤖 Бот: {answer}")
