from __future__ import annotations

import time

import numpy as np

from idri import IdentifierEncoder


def _try_import_optional():
    rapidfuzz_fuzz = None
    tfidf = None
    cosine = None

    try:
        from rapidfuzz import fuzz

        rapidfuzz_fuzz = fuzz
    except Exception:
        pass

    try:
        from sklearn.feature_extraction.text import TfidfVectorizer
        from sklearn.metrics.pairwise import cosine_similarity

        tfidf = TfidfVectorizer(analyzer="char", ngram_range=(3, 5))
        cosine = cosine_similarity
    except Exception:
        pass

    return rapidfuzz_fuzz, tfidf, cosine


def main() -> None:
    pairs = [
        ("ACME INDUSTRIAL SA DE CV", "ACME INDUSTRIAL"),
        ("INV-2024-001-03", "INV-2024-001"),
        ("hammer drill set", "drill set"),
        ("TOPER PULIDORA 4 1/2", "TOPER PULIDORA 4 1 2"),
        ("OMNISPHERE WM", "OMNISPHERE"),
    ]

    enc = IdentifierEncoder(profile="word_ngram")

    print("== idri ==")
    t0 = time.perf_counter()
    for a, b in pairs:
        print(f"{a!r} vs {b!r}: {enc.similarity(a, b):.4f}")
    print(f"time: {(time.perf_counter() - t0) * 1e3:.2f} ms")

    fuzz, tfidf, cosine = _try_import_optional()

    if fuzz is not None:
        print("\\n== RapidFuzz ratio ==")
        for a, b in pairs:
            print(f"{a!r} vs {b!r}: {fuzz.ratio(a, b) / 100.0:.4f}")
    else:
        print("\\nRapidFuzz not installed; skipping.")

    if tfidf is not None and cosine is not None:
        print("\\n== char n-gram TF-IDF cosine ==")
        all_texts = [t for pair in pairs for t in pair]
        mat = tfidf.fit_transform(all_texts)
        for i, (a, b) in enumerate(pairs):
            va = mat[2 * i]
            vb = mat[2 * i + 1]
            score = float(cosine(va, vb)[0, 0])
            print(f"{a!r} vs {b!r}: {score:.4f}")
    else:
        print("scikit-learn not installed; skipping TF-IDF baseline.")

    print("\\n== exact normalized match baseline ==")
    for a, b in pairs:
        print(f"{a!r} vs {b!r}: {1.0 if a.lower().strip() == b.lower().strip() else 0.0:.4f}")


if __name__ == "__main__":
    main()
