import pytest

from app.services.catalog.text import clean_title, normalise_brand, normalise_text


@pytest.mark.parametrize("raw,expected", [
    ("  Trail Runner  ", "Trail Runner"),
    ("Men’s Jacket", "Men’s Jacket"),
    ("ﬁne wool", "fine wool"),          # NFKC folds the fi ligature
    ("２００", "200"),           # full-width digits
    ("a​b", "ab"),                      # zero-width space
    ("a b", "a b"),                     # non-breaking space
    ("a   b", "a b"),
    ("", None),
    ("   ", None),
    (None, None),
])
def test_normalise_text(raw, expected):
    assert normalise_text(raw) == expected


def test_empty_string_becomes_none_not_empty():
    # "" and None must not produce two hashes or two code paths.
    assert normalise_text("") is None


@pytest.mark.parametrize("raw,brand,expected", [
    ("Salomon - Trail Runner", "Salomon", "Trail Runner"),
    ("Salomon | Trail Runner", "Salomon", "Trail Runner"),
    ("Salomon: Trail Runner", "Salomon", "Trail Runner"),
    ("Trail Runner", "Salomon", "Trail Runner"),
    ("Trail Runner Pro (SKU-88421-B)", None, "Trail Runner Pro"),
    ("Trail Runner Pro [item: 42]", None, "Trail Runner Pro"),
    ("THE COMPLETE SNOWBOARD", None, "The Complete Snowboard"),
    ("XL", None, "XL"),
])
def test_clean_title(raw, brand, expected):
    assert clean_title(raw, brand) == expected


def test_brand_strip_never_empties_the_title():
    # A title that is only the brand needs the brand more than the separation.
    assert clean_title("Salomon", "Salomon") == "Salomon"
    assert clean_title("Salomon - S", "Salomon") == "Salomon - S"


def test_shop_name_vendor_is_rejected():
    # 8 of 17 products in the live store carry the shop name as vendor, which is
    # Shopify's default when the merchant leaves it blank.
    assert normalise_brand("Galaxiq", "Galaxiq") is None
    assert normalise_brand("galaxiq", "Galaxiq") is None
    assert normalise_brand("Galaxiq Store", "Galaxiq") is None


def test_a_similar_looking_real_brand_is_not_mistaken_for_the_shop_name():
    # SequenceMatcher rates "galaxy" vs "galaxiq" at 0.769, so any fuzzy
    # threshold low enough to catch "Galaxiq Store" also destroys this brand.
    assert normalise_brand("Galaxy", "Galaxiq") == "Galaxy"
    assert normalise_brand("Galactic", "Galaxiq") == "Galactic"


@pytest.mark.parametrize("v", ["n/a", "N/A", "none", "unknown", "default",
                               "generic", "no brand", "-", "", None])
def test_placeholder_vendors_rejected(v):
    assert normalise_brand(v, "Galaxiq") is None


def test_real_vendor_kept():
    assert normalise_brand("Snowboard Vendor", "Galaxiq") == "Snowboard Vendor"


def test_casing_canonicalised_against_known_brands():
    assert normalise_brand("salomon", "Galaxiq", ["Salomon"]) == "Salomon"
    assert normalise_brand("SALOMON", "Galaxiq", ["Salomon"]) == "Salomon"
