from unittest.mock import MagicMock, patch

from GramAddict.core.q_nav_graph import QNavGraph


def test_tap_home_tab_recovery_from_homescreen():
    """
    TDD: Reproduce the failure where tap_home_tab fails because the bot is on
    the Android Homescreen (app.lawnchair), and verify that it recovers
    via app_start instead of enterring an auto-repair loop.
    """
    # 1. Setup Mock Device
    mock_device = MagicMock()
    mock_device.app_id = "com.instagram.android"
    # Return homescreen package to simulate context loss
    mock_device._get_current_app.return_value = "app.lawnchair"

    # 2. Mock DeviceV2 responses
    mock_device.dump_hierarchy.return_value = "<hierarchy />"
    mock_device.app_start.return_value = True

    # 3. Initialize NavGraph
    graph = QNavGraph(mock_device)
    graph.current_state = "ProfileFeed"  # Assume stale state

    # 4. Patch TelepathicEngine.get_instance to return a mock engine
    with (
        patch("GramAddict.core.telepathic_engine.TelepathicEngine.get_instance") as mock_get_instance,
        patch("GramAddict.core.goap.PathMemory.learn_path"),
        patch("GramAddict.core.goap.PathMemory.recall_path", return_value=None),
        patch("GramAddict.core.qdrant_memory.ScreenMemoryDB._get_embedding", return_value=[0] * 1536),
        patch(
            "GramAddict.core.situational_awareness.SituationalAwarenessEngine.ensure_clear_screen", return_value=False
        ),
        patch("GramAddict.core.q_nav_graph.time.sleep"),
    ):
        mock_engine = MagicMock()
        mock_get_instance.return_value = mock_engine

        # Simulate Context Guard hitting: return None forever
        mock_engine.find_best_node.return_value = None

        # 5. Execute
        # We expect this to return False gracefully after 3 attempts, without infinitely looping
        success = graph.navigate_to("ExploreFeed", zero_engine=None)

        # 6. Assertion
        assert not success, "Navigation should fail gracefully when context cannot be recovered"
        assert mock_device.app_start.called, "Should have force-started the app when context was lost"
