"""
Тесты для BotResolver и ContextFactory
"""

import pytest
from unittest.mock import AsyncMock, MagicMock

from aiogram import Bot

from ui_router import (
    UIRouter,
    Scene,
    EventHandler,
)
from ui_router.schema import SendMessageAction, MessageContent
from ui_router.events import EventData, EventSourceType
from ui_router.services import SharedServices


class TestBotResolver:
    """Тесты для BotResolver"""

    @pytest.mark.asyncio
    async def test_bot_resolver_called_for_scheduled_events(self, shared_services):
        """BotResolver должен вызываться для SCHEDULED событий"""
        # Mock bot resolver
        bot = MagicMock(spec=Bot)
        bot.id = 123456
        bot_resolver = AsyncMock(return_value=bot)

        # Создаём схему
        schema = UIRouter(
            name="test",
            initial_scene="start",
            scenes=[Scene(id="start", name="Start", default_content=None, handlers=[])],
            event_handlers=[
                EventHandler(
                    event_name="scheduled_task",
                    actions=[
                        SendMessageAction(
                            content=MessageContent(text="Task executed!"),
                        )
                    ],
                )
            ],
        )

        # Создаём executor с bot_resolver
        from ui_router.router import UIRouterExecutor

        # Обновляем shared services с bot_resolver
        shared_services.bot_resolver = bot_resolver

        executor = UIRouterExecutor(
            schema=schema,
            shared=shared_services,
        )

        # Инициализируем навигацию для пользователя
        await executor.navigation_service.initialize(
            bot_id=123456,
            user_id=456,
            chat_id=456,
            initial_scene="start",
        )

        # Создаём SCHEDULED событие без bot instance
        event = EventData(
            event_name="scheduled_task",
            source_type=EventSourceType.SCHEDULED,
            data={},
            bot_id=123456,
            user_id=456,
            chat_id=456,
        )

        # Обрабатываем событие
        await executor.event_dispatcher.dispatch(event, bot=None)

        # Проверяем что bot_resolver был вызван
        bot_resolver.assert_called_once_with(123456)

    @pytest.mark.asyncio
    async def test_bot_not_resolved_if_provided(self, shared_services):
        """BotResolver НЕ должен вызываться если bot передан"""
        bot = MagicMock(spec=Bot)
        bot.id = 123456
        bot_resolver = AsyncMock(return_value=bot)

        schema = UIRouter(
            name="test",
            initial_scene="start",
            scenes=[Scene(id="start", name="Start", default_content=None, handlers=[])],
            event_handlers=[
                EventHandler(
                    event_name="test_event",
                    actions=[
                        SendMessageAction(
                            content=MessageContent(text="Hello!"),
                        )
                    ],
                )
            ],
        )

        from ui_router.router import UIRouterExecutor

        # Обновляем shared services с bot_resolver
        shared_services.bot_resolver = bot_resolver

        executor = UIRouterExecutor(
            schema=schema,
            shared=shared_services,
        )

        await executor.navigation_service.initialize(
            bot_id=123456,
            user_id=456,
            chat_id=456,
            initial_scene="start",
        )

        event = EventData(
            event_name="test_event",
            source_type=EventSourceType.INTERNAL,
            data={},
            bot_id=123456,
            user_id=456,
            chat_id=456,
        )

        # Передаём bot явно
        await executor.event_dispatcher.dispatch(event, bot=bot)

        # bot_resolver НЕ должен быть вызван
        bot_resolver.assert_not_called()


class TestContextFactory:
    """Тесты для ContextFactory"""

    @pytest.mark.asyncio
    async def test_context_factory_resolves_flags(self, shared_services):
        """ContextFactory должен резолвить флаги при создании контекста"""
        from ui_router.router import UIRouterExecutor
        from ui_router.schema import Flag, FlagGetter
        from ui_router.state.context import NavigationState

        bot = MagicMock(spec=Bot)
        bot.id = 123456

        schema = UIRouter(
            name="test",
            initial_scene="start",
            scenes=[
                Scene(
                    id="start",
                    name="Start",
                    default_content=None,
                    handlers=[],
                    flags=[
                        Flag(
                            name="test_flag",
                            getter=FlagGetter(type="static", value="test_value"),
                        )
                    ],
                )
            ],
        )

        executor = UIRouterExecutor(
            schema=schema,
            shared=shared_services,
        )

        nav_state = NavigationState(current_scene="start")

        # Создаём контекст через ContextFactory
        scene = schema.get_scene("start")
        context = await executor.context_factory.create_context(
            navigation_state=nav_state,
            scene_id="start",
            bot=bot,
            user_id=456,
            chat_id=456,
            scene=scene,
        )

        # Проверяем что флаг зарезолвился
        assert context.get_flag("test_flag") == "test_value"
