"""
Search and Explore Navigation Tests
Tests the Visual Intent Resolver on Search and Explore feed workflows.
"""

import pytest

from GramAddict.core.perception.intent_resolver import IntentResolver
from GramAddict.core.perception.spatial_parser import SpatialParser


def run_workflow_test(fixture_base_name, intent, expected_desc_or_id, make_real_device_with_image):
    xml_path = f"tests/fixtures/{fixture_base_name}.xml"
    jpg_path = f"tests/fixtures/{fixture_base_name}.jpg"

    with open(xml_path, "r", encoding="utf-8") as f:
        xml = f.read()

    parser = SpatialParser()
    root = parser.parse(xml)
    candidates = parser.get_clickable_nodes(root)

    device = make_real_device_with_image(jpg_path)
    resolver = IntentResolver()

    # Execute real LLM call, NO MOCKING
    result = resolver.resolve(intent, candidates, device)

    assert result is not None, f"VLM returned None for '{intent}'"

    rid = (result.resource_id or "").lower()
    desc = (result.content_desc or "").lower()
    text = (result.text or "").lower()

    matched = False
    for expected in expected_desc_or_id.split("|"):
        expected = expected.strip().lower()
        if expected in rid or expected in desc or expected in text:
            matched = True
            break

    assert matched, (
        f"VLM picked wrong element! Expected one of '{expected_desc_or_id}', "
        f"but got id='{rid}', desc='{desc}', text='{text}'"
    )


@pytest.mark.live_llm
def test_search_input(make_real_device_with_image):
    run_workflow_test(
        "search_feed_dump", "tap the search input field at the top of the screen", "search", make_real_device_with_image
    )


@pytest.mark.live_llm
def test_explore_feed_first_post(make_real_device_with_image):
    # It might pick an image ID or content-desc. Just checking it's not None.
    xml_path = "tests/fixtures/explore_feed_dump.xml"
    jpg_path = "tests/fixtures/explore_feed_dump.jpg"

    with open(xml_path, "r", encoding="utf-8") as f:
        xml = f.read()

    parser = SpatialParser()
    root = parser.parse(xml)
    candidates = parser.get_clickable_nodes(root)

    device = make_real_device_with_image(jpg_path)
    resolver = IntentResolver()

    result = resolver.resolve("tap first post", candidates, device)
    assert result is not None, "VLM returned None for 'tap first post'"
    
    # Strictly verify that it picked an image button or post, NOT the search bar
    rid = (result.resource_id or "").lower()
    desc = (result.content_desc or "").lower()
    
    # A valid grid post has an image_button resource ID or "photo" / "Reel" in description
    is_valid_post = "image_button" in rid or "photo" in desc or "reel" in desc
    assert is_valid_post, f"VLM picked the wrong element! Selected id='{rid}', desc='{desc}'"
