"""`normalize_keyword` (spec Imports §3.1, §4.2) : NFC + trim + minuscules + espaces réduits.

C'est cette forme qui est stockée dans `keywords.keyword` et qui rend fiable l'unicité
`(org_id, locale, keyword)` : deux exports de plateformes différentes n'écrivent jamais le
même mot-clé de la même façon (casse, espaces insécables, é précomposé ou décomposé).
"""

import unicodedata

import pytest

from app.keywords.normalize import normalize_keyword


@pytest.mark.parametrize(
    ("raw", "expected"),
    [
        # Trim.
        ("  chaussures  ", "chaussures"),
        ("\tchaussures\n", "chaussures"),
        # Minuscules.
        ("Chaussures De Sport", "chaussures de sport"),
        ("CHAUSSURES", "chaussures"),
        ("CAFÉ", "café"),
        ("ÊTRE OU NE PAS ÊTRE", "être ou ne pas être"),
        # Espaces réduits (y compris tabulations, retours et espaces insécables des exports).
        ("chaussures   de    sport", "chaussures de sport"),
        ("chaussures\tde\nsport", "chaussures de sport"),
        ("chaussures de sport", "chaussures de sport"),
        ("  Chaussures   DE   sport ", "chaussures de sport"),
        # Chaîne vide ou blanche : rendue vide — au pipeline d'en faire une ligne en erreur.
        ("", ""),
        ("   ", ""),
        # Les caractères non alphabétiques ne sont jamais touchés (marques, chiffres, tirets).
        ("Nike Air Max 90", "nike air max 90"),
        ("t-shirt col v", "t-shirt col v"),
    ],
)
def test_normalize_keyword(raw: str, expected: str) -> None:
    assert normalize_keyword(raw) == expected


def test_nfc_folds_decomposed_forms() -> None:
    """« café » décomposé (e + accent combinant) et précomposé sont le même mot-clé."""
    decomposed = "cafe\u0301"  # e + U+0301 COMBINING ACUTE ACCENT
    precomposed = "caf\u00e9"  # e accent aigu precompose
    assert decomposed != precomposed
    assert normalize_keyword(decomposed) == normalize_keyword(precomposed) == precomposed


def test_result_is_nfc() -> None:
    """Invariant : la sortie est toujours en NFC, même après passage en minuscules."""
    for raw in ("CAFÉ", "ÉTÉ", "ÉTÉ  À  PARIS"):
        out = normalize_keyword(raw)
        assert out == unicodedata.normalize("NFC", out)


@pytest.mark.parametrize(
    "raw",
    ["  Chaussures  DE sport ", "CAFÉ", "", "nike air max 90"],
)
def test_idempotent(raw: str) -> None:
    once = normalize_keyword(raw)
    assert normalize_keyword(once) == once
