"""Text normalization for the fuzzy/text-fallback match key.

Goal: collapse cosmetic differences between sources (accents, case, "feat."
clauses, "- Remastered 2011" / "(Live)" qualifiers, punctuation) so the same
song lands on the same key, while keeping genuinely different versions
(e.g. Remix) distinct.
"""
import re
import unicodedata

_FEAT = re.compile(r"\s*[\(\[]?\s*(feat|ft|featuring|with)\.?\s.*$", re.IGNORECASE)
_BRACKETS = re.compile(r"\s*[\(\[][^\)\]]*[\)\]]")
# trailing "- Remastered 2011", "- Live", "- Mono", "- 2009 Remaster", etc.
_DASH_QUALIFIER = re.compile(
    r"\s*-\s*.*?\b(remaster(ed)?|remastered|live|mono|stereo|version|edit|"
    r"anniversary|deluxe|bonus|radio|single)\b.*$",
    re.IGNORECASE,
)
_NON_ALNUM = re.compile(r"[^\w\s]", re.UNICODE)
_WS = re.compile(r"\s+")


def strip_accents(s: str) -> str:
    s = unicodedata.normalize("NFKD", s)
    return "".join(c for c in s if not unicodedata.combining(c))


def _base(s: str) -> str:
    s = strip_accents(s or "").lower()
    s = _NON_ALNUM.sub(" ", s)
    return _WS.sub(" ", s).strip()


def normalize_artist(name: str) -> str:
    return _base(name)


def normalize_title(title: str) -> str:
    s = title or ""
    s = _FEAT.sub("", s)
    s = _DASH_QUALIFIER.sub("", s)
    s = _BRACKETS.sub("", s)
    return _base(s)


def norm_key(artist: str, title: str) -> str:
    """Identity key when no recording MBID is available."""
    return f"{normalize_artist(artist)}|{normalize_title(title)}"
