"""Fuzzy deduplication for trending topics."""

from typing import List, Dict, Set
from thefuzz import fuzz

from config import FUZZY_THRESHOLD


def deduplicate_topics(items: List[dict]) -> List[dict]:
    """
    Deduplicate topics using fuzzy string matching.

    Groups similar topics together, keeping the highest-ranked instance
    as the representative while tracking all contributing sources.

    Args:
        items: List of trend item dictionaries

    Returns:
        Deduplicated list with 'sources' field showing all contributors
    """
    if not items:
        return []

    # Group items by similarity into clusters
    clusters: List[Dict] = []

    for item in items:
        topic = item["topic_name"].lower().strip()
        matched = False

        for cluster in clusters:
            # Check similarity against cluster representative
            rep_topic = cluster["representative"]["topic_name"].lower().strip()
            ratio = fuzz.token_sort_ratio(topic, rep_topic)

            if ratio >= FUZZY_THRESHOLD:
                # Add to existing cluster
                cluster["members"].append(item)
                cluster["sources"].add(item["source"])
                cluster["regions"].add(item["region"])
                matched = True
                break

        if not matched:
            # Create new cluster
            clusters.append(
                {
                    "representative": item,
                    "members": [item],
                    "sources": {item["source"]},
                    "regions": {item["region"]},
                }
            )

    # Build deduplicated list
    result = []
    for cluster in clusters:
        # Use highest-ranked (lowest rank number) as representative
        best = min(cluster["members"], key=lambda x: x["rank"])

        # Enrich with cross-source data
        best["sources"] = sorted(list(cluster["sources"]))
        best["source_count"] = len(cluster["sources"])
        best["regions"] = sorted(list(cluster["regions"]))
        best["all_urls"] = {
            m["source"]: m["url"] for m in cluster["members"] if m.get("url")
        }

        result.append(best)

    return result
