"""
Groups OddsEntry objects from different bookmakers into the same real-world
event, so we can compare their prices for the same match.

Team names are rarely spelled identically across books ("Man United" vs
"Manchester United"), so this does simple normalization + fuzzy matching
rather than exact string matching.
"""

from collections import defaultdict
from typing import List, Dict, Tuple
from difflib import SequenceMatcher

from scrapers.base import OddsEntry

# Add aliases here as you discover mismatches between books.
TEAM_ALIASES = {
    "man united": "manchester united",
    "man utd": "manchester united",
    "spurs": "tottenham hotspur",
    "gor mahia fc": "gor mahia",
    "afc leopards sc": "afc leopards",
}


def normalize_team(name: str) -> str:
    name = name.strip().lower()
    return TEAM_ALIASES.get(name, name)


def similar(a: str, b: str, threshold: float = 0.82) -> bool:
    return SequenceMatcher(None, a, b).ratio() >= threshold


def group_by_event(entries: List[OddsEntry]) -> Dict[Tuple[str, str], List[OddsEntry]]:
    """
    Returns a dict keyed by (home_team_normalized, away_team_normalized)
    -> list of all OddsEntry rows (from all books) for that event.
    """
    events: Dict[Tuple[str, str], List[OddsEntry]] = defaultdict(list)
    known_keys: List[Tuple[str, str]] = []

    for entry in entries:
        home_norm = normalize_team(entry.home_team)
        away_norm = normalize_team(entry.away_team)

        # try to match against an existing event key first (fuzzy), so
        # slightly different spellings still land in the same bucket
        matched_key = None
        for key in known_keys:
            if similar(home_norm, key[0]) and similar(away_norm, key[1]):
                matched_key = key
                break

        key = matched_key or (home_norm, away_norm)
        if key not in known_keys:
            known_keys.append(key)

        events[key].append(entry)

    return events
