"""Tests para match_pois_to_interests."""

from match_pois_to_interests import match_pois_to_interests

POIS_SAMPLE = [
    {
        "id": 1,
        "lat": 40.41,
        "lon": -3.70,
        "name": "Museo del Prado",
        "category": "museum",
        "tags": {"tourism": "museum", "name": "Museo del Prado"},
    },
    {
        "id": 2,
        "lat": 40.42,
        "lon": -3.71,
        "name": "Bar El Tigre",
        "category": "bar",
        "tags": {"amenity": "bar", "name": "Bar El Tigre"},
    },
    {
        "id": 3,
        "lat": 40.43,
        "lon": -3.72,
        "name": "Galería de Arte Moderno",
        "category": "gallery",
        "tags": {"tourism": "gallery", "art": "modern"},
    },
]


def test_pois_que_matchean_parcialmente_por_categoria_y_nombre():
    """pois que matchean parcialmente por categoria y nombre"""
    interests = [{"name": "arte", "keywords": ["museo", "museum", "arte", "galería"], "weight": 1.0}]
    result = match_pois_to_interests(POIS_SAMPLE, interests)

    ids = [p["id"] for p in result]
    # museo matchea por category "museum" (0.5) + nombre "Museo" (0.3) + tag "museum" (0.2) = 1.0
    assert 1 in ids
    # galería: sin match de categoria exacta (gallery != keywords), pero nombre contiene "Arte" -> check keywords
    # keywords: "museo", "museum", "arte", "galería" — "arte" en "galería de arte moderno" -> 0.3
    assert 3 in ids
    # bar no matchea ninguno
    assert 2 not in ids
    # el museo debe tener score mas alto que la galeria
    museo = next(p for p in result if p["id"] == 1)
    galeria = next(p for p in result if p["id"] == 3)
    assert museo["score"] > galeria["score"]
    assert "arte" in museo["matched_interests"]
    assert "arte" in galeria["matched_interests"]


def test_pois_sin_match_retorna_lista_vacia():
    """pois sin match retorna lista vacia"""
    pois = [
        {"id": 10, "lat": 40.0, "lon": -3.0, "name": "Parking Norte", "category": "parking", "tags": {"amenity": "parking"}},
        {"id": 11, "lat": 40.1, "lon": -3.1, "name": "Gasolinera BP", "category": "fuel", "tags": {"amenity": "fuel"}},
    ]
    interests = [{"name": "arte", "keywords": ["museo", "museum", "galería", "pintura"], "weight": 1.0}]
    result = match_pois_to_interests(pois, interests)
    assert result == []


def test_multiples_intereses_con_diferentes_weights_acumulan_score():
    """multiples intereses con diferentes weights acumulan score"""
    pois = [
        {
            "id": 20,
            "lat": 40.5,
            "lon": -3.5,
            "name": "Café Museo",
            "category": "cafe",
            "tags": {"amenity": "cafe", "tourism": "museum"},
        }
    ]
    interests = [
        {"name": "arte", "keywords": ["museum", "museo", "arte"], "weight": 1.0},
        {"name": "gastronomia", "keywords": ["cafe", "restaurant", "bar"], "weight": 0.8},
    ]
    result = match_pois_to_interests(pois, interests)
    assert len(result) == 1
    poi = result[0]
    # arte: nombre "Café Museo" contiene "museo" (0.3) + tag "museum" (0.2) = 0.5 * 1.0 = 0.5
    # gastronomia: category "cafe" in keywords (0.5) + nombre "Café" contiene "cafe" (0.3) = 0.8 * 0.8 = 0.64
    # total ~ 1.14
    assert poi["score"] > 1.0
    assert "arte" in poi["matched_interests"]
    assert "gastronomia" in poi["matched_interests"]
    assert len(poi["matched_interests"]) == 2


def test_max_results_limita_resultados():
    pois = [
        {"id": i, "lat": 40.0, "lon": -3.0, "name": f"Museo {i}", "category": "museum", "tags": {}}
        for i in range(20)
    ]
    interests = [{"name": "arte", "keywords": ["museum", "museo"], "weight": 1.0}]
    result = match_pois_to_interests(pois, interests, max_results=5)
    assert len(result) == 5


def test_inputs_no_mutados():
    pois = [
        {"id": 1, "lat": 40.0, "lon": -3.0, "name": "Museo A", "category": "museum", "tags": {}}
    ]
    interests = [{"name": "arte", "keywords": ["museum"], "weight": 1.0}]
    original_poi_keys = set(pois[0].keys())
    match_pois_to_interests(pois, interests)
    # el poi original no debe tener score ni matched_interests
    assert set(pois[0].keys()) == original_poi_keys


if __name__ == "__main__":
    test_pois_que_matchean_parcialmente_por_categoria_y_nombre()
    print("PASS: pois que matchean parcialmente por categoria y nombre")

    test_pois_sin_match_retorna_lista_vacia()
    print("PASS: pois sin match retorna lista vacia")

    test_multiples_intereses_con_diferentes_weights_acumulan_score()
    print("PASS: multiples intereses con diferentes weights acumulan score")

    test_max_results_limita_resultados()
    print("PASS: max_results limita resultados")

    test_inputs_no_mutados()
    print("PASS: inputs no mutados")

    print("---")
    print("All tests passed.")
