from unittest.mock import MagicMock, patch

from GramAddict.core.bot_flow import _run_zero_latency_feed_loop


def test_bot_flow_unlearns_on_context_loss():
    """Prove that bot_flow calls unlearn_current_state when context is completely lost (3 misses)."""
    device = MagicMock()
    # Provide a dummy dump hierarchy
    device.dump_hierarchy.return_value = "<hierarchy></hierarchy>"
    device.get_info.return_value = {"displayWidth": 1080, "displayHeight": 2400}

    session_state = MagicMock()

    with (
        patch("GramAddict.core.behaviors.PluginRegistry.get_instance") as MockRegistry,
        patch("GramAddict.core.bot_flow.sleep"),
        patch("GramAddict.core.physics.humanized_input.humanized_scroll"),
        patch("GramAddict.core.bot_flow._humanized_scroll"),
    ):
        from GramAddict.core.behaviors import BehaviorResult

        mock_registry_instance = MockRegistry.return_value
        mock_registry_instance.execute_all.return_value = [
            BehaviorResult(executed=True, should_skip=True, metadata={"return_code": "CONTEXT_LOST"})
        ]

        mock_cognitive_stack = MagicMock()
        dopamine_mock = MagicMock()
        dopamine_mock.is_app_session_over.return_value = False
        dopamine_mock.wants_to_doomscroll.return_value = False

        def stack_get(key):
            if key == "radome":
                return None
            elif key == "dopamine":
                return dopamine_mock
            return MagicMock()

        mock_cognitive_stack.get.side_effect = stack_get

        result = _run_zero_latency_feed_loop(
            device=device,
            zero_engine=MagicMock(),
            nav_graph=MagicMock(),
            configs=MagicMock(),
            session_state=session_state,
            job_target="test_feed",
            cognitive_stack=mock_cognitive_stack,
        )

        # Assert (RED)
        assert result == "CONTEXT_LOST"
