"""Filtra y rankea POIs segun un perfil de intereses del usuario."""


def match_pois_to_interests(
    pois: list[dict],
    interests: list[dict],
    max_results: int = 10,
) -> list[dict]:
    """Filtra y rankea una lista de POIs segun un perfil de intereses.

    Calcula un score para cada POI basado en matches de categoria, nombre
    y tags contra los keywords de cada interes. Solo retorna POIs con score > 0,
    ordenados por score descendente, hasta max_results.

    Args:
        pois: Lista de POIs con campos id, lat, lon, name, category, tags.
        interests: Lista de intereses con campos name, keywords y weight.
        max_results: Numero maximo de resultados a retornar.

    Returns:
        Lista de POIs enriquecidos con score y matched_interests, ordenados
        por score descendente. Lista vacia si ningun POI matchea.
    """
    scored: list[dict] = []

    for poi in pois:
        total_score = 0.0
        matched: list[str] = []

        category = (poi.get("category") or "").lower()
        name = (poi.get("name") or "").lower()
        tags = poi.get("tags") or {}
        tag_values = " ".join(str(v) for v in tags.values()).lower()

        for interest in interests:
            keywords: list[str] = [kw.lower() for kw in (interest.get("keywords") or [])]
            weight: float = float(interest.get("weight", 1.0))
            interest_name: str = interest.get("name", "")

            interest_score = 0.0

            # Match de categoria: 0.5 puntos si la categoria aparece en keywords
            if any(kw == category for kw in keywords):
                interest_score += 0.5

            # Match de nombre: 0.3 puntos si algun keyword es substring del nombre
            if any(kw in name for kw in keywords):
                interest_score += 0.3

            # Match de tags: 0.2 puntos si algun keyword aparece en valores de tags
            if any(kw in tag_values for kw in keywords):
                interest_score += 0.2

            if interest_score > 0:
                total_score += interest_score * weight
                matched.append(interest_name)

        if total_score > 0:
            scored.append({**poi, "score": round(total_score, 6), "matched_interests": matched})

    scored.sort(key=lambda p: p["score"], reverse=True)
    return scored[:max_results]
