"""
ContextFactory - фабрика для создания ExecutionContext с резолвом флагов

Убирает дублирование между router.py и event_dispatcher.py
"""

import logging
from typing import TYPE_CHECKING, Any

from aiogram import Bot
from aiogram.types import Message, CallbackQuery

from .context import ExecutionContext, NavigationState, EventMode, NavigationManager
from ui_router.schema import Scene

if TYPE_CHECKING:
    from ui_router.rules.flags import FlagResolver
    from ui_router.schema import UIRouter

logger = logging.getLogger(__name__)


class ContextFactory:
    """
    Фабрика для создания ExecutionContext с автоматическим резолвом флагов

    Централизует логику создания контекста и резолва флагов,
    убирая дублирование кода между разными частями системы.
    """

    def __init__(
        self,
        flag_resolver: "FlagResolver",
        navigation_manager: NavigationManager,
        schema: "UIRouter",
    ) -> None:
        """
        Инициализировать ContextFactory

        Args:
            flag_resolver: FlagResolver для резолва флагов
            navigation_manager: NavigationManager для управления навигацией
            schema: UIRouter схема
        """
        self.flag_resolver = flag_resolver
        self.navigation_manager = navigation_manager
        self.schema = schema

    async def create_context(
        self,
        navigation_state: NavigationState,
        scene_id: str,
        bot: Bot,
        user_id: int,
        chat_id: int,
        event: Message | CallbackQuery | None = None,
        event_mode: EventMode = EventMode.MESSAGE,
        event_data: dict[str, Any] | None = None,
        scene: Scene | None = None,
    ) -> ExecutionContext:
        """
        Создать ExecutionContext с резолвом флагов

        Args:
            navigation_state: Навигационное состояние
            scene_id: ID сцены
            bot: Bot instance
            user_id: ID пользователя
            chat_id: ID чата
            event: Message или CallbackQuery (опционально)
            event_mode: Режим выполнения
            event_data: Дополнительные данные
            scene: Scene для резолва флагов (если None - берётся из schema)

        Returns:
            ExecutionContext с зарезолвленными флагами
        """
        context = ExecutionContext(
            navigation_manager=self.navigation_manager,
            navigation_state=navigation_state,
            scene_id=scene_id,
            bot=bot,
            user_id=user_id,
            chat_id=chat_id,
            event=event,
            event_mode=event_mode,
            event_data=event_data or {},
        )

        context.event_data["ui_router_schema"] = self.schema

        if scene or scene_id:
            current_scene = scene or self.schema.get_scene(scene_id)
            if current_scene:
                await self.resolve_flags(context, current_scene, event)

        return context

    async def resolve_flags(
        self,
        context: ExecutionContext,
        scene: Scene,
        event: Message | CallbackQuery | None = None,
    ) -> None:
        """
        Резолвить все флаги для контекста

        Делегирует резолв флагов FlagResolver.

        Args:
            context: Контекст для резолва флагов
            scene: Сцена с флагами
            event: Событие (для function getters)
        """
        await self.flag_resolver.resolve_scene_flags(scene, context, event)
