"""
SceneRenderer - рендеринг сцен

Отвечает за полный цикл входа в сцену:
- Резолв флагов
- Выполнение on_enter хуков
- Отображение контента
- Отправка дополнительных сообщений
"""

import logging
from typing import TYPE_CHECKING

from ui_router.analytics import AnalyticsEvent, AnalyticsEventType
from ui_router.state.context import ExecutionContext
from ui_router.exceptions import SceneNotFoundError
from ui_router.schema import TransitionType

if TYPE_CHECKING:
    from aiogram.types import CallbackQuery, Message

    from ui_router.analytics import AnalyticsCollector
    from ui_router.rules.flags import FlagResolver
    from ui_router.execution.actions import ActionExecutor
    from ui_router.schema import UIRouter
    from ui_router.services.content_service import ContentService

logger = logging.getLogger(__name__)


class SceneRenderer:
    """
    Рендеринг сцен

    Отделяет логику рендеринга от навигации.
    NavigationService управляет состоянием навигации,
    а SceneRenderer отвечает за отображение сцены.
    """

    def __init__(
        self,
        flag_resolver: "FlagResolver",
        content_service: "ContentService",
        action_executor: "ActionExecutor",
        schema: "UIRouter",
        analytics_collector: "AnalyticsCollector | None" = None,
    ) -> None:
        """
        Инициализировать SceneRenderer

        Args:
            flag_resolver: FlagResolver для резолва флагов
            content_service: ContentService для отображения контента
            action_executor: ActionExecutor для выполнения actions
            schema: UIRouter схема
            analytics_collector: Коллектор аналитики (опционально)
        """
        self.flag_resolver = flag_resolver
        self.content_service = content_service
        self.action_executor = action_executor
        self.schema = schema
        self.analytics_collector = analytics_collector

    async def enter_scene(
        self,
        scene_id: str,
        context: ExecutionContext,
        transition: TransitionType = TransitionType.SEND,
        message: "Message | None" = None,
        callback_query: "CallbackQuery | None" = None,
    ) -> None:
        """
        Войти в сцену (показать контент)

        Выполняет полный цикл входа на сцену:
        1. Валидирует сцену
        2. Резолвит флаги через flag_resolver
        3. Выполняет on_enter actions
        4. Резолвит и отправляет контент
        5. Отправляет дополнительные сообщения
        6. Сохраняет состояние

        Args:
            scene_id: ID сцены для входа
            context: Контекст выполнения
            transition: Тип перехода (SEND, EDIT_SMART, ANSWER)
            message: Сообщение (для MESSAGE режима)
            callback_query: Callback query (для CALLBACK режима)
        """
        scene = self.schema.get_scene(scene_id)
        if not scene:
            raise SceneNotFoundError(scene_id)

        await self.flag_resolver.resolve_scene_flags(scene, context, message or callback_query)

        for action in scene.on_enter:
            await self.action_executor.execute(action, context, message or callback_query)

        content, keyboard = await self.content_service.resolve_scene_content(
            scene, context, self.flag_resolver.get_variable_for_condition, self.flag_resolver.resolve_condition_value
        )

        if content or keyboard:
            await self.content_service.display_content(
                content=content,
                keyboard=keyboard,
                user_id=context.chat_id,
                transition=transition,
                callback_query=callback_query,
                context=context,
            )

        if scene.messages:
            await self.content_service.send_additional_messages(scene.messages, context.chat_id, context)

        if self.analytics_collector:
            await self.analytics_collector.track(
                AnalyticsEvent(
                    event_type=AnalyticsEventType.SCENE_ENTER,
                    bot_id=context.bot.id,
                    user_id=context.user_id,
                    chat_id=context.chat_id,
                    scene_id=scene_id,
                )
            )

        try:
            await context.save_to_storage()
        except Exception:
            logger.exception("Failed to save navigation state after entering scene '%s'", scene_id)
