"""Word-level matching: tokenize both strings, match words individually, aggregate.

Hypothesis: matching word-by-word keeps each comparison in JW's sweet spot
(same-length, character substitutions) and handles multi-word queries naturally.
"""

from rapidfuzz.distance import JaroWinkler
from harness import evaluate


def word_score(query, candidate):
    """Match query words to candidate words, return average best-match score."""
    q_words = query.lower().split()
    c_words = candidate.lower().split()

    if not q_words or not c_words:
        return 0.0

    # For each query word, find the best matching candidate word
    total = 0.0
    for qw in q_words:
        best = 0.0
        for cw in c_words:
            s = JaroWinkler.similarity(qw, cw)
            if s > best:
                best = s
        total += best

    return total / len(q_words)


if __name__ == "__main__":
    evaluate(word_score, name="09 - Word-level Jaro-Winkler (avg best match)")
