"""Iteration: Reverse Jaro-Winkler to fix first-char-wrong problem.

Gemini's idea: JW has prefix bias, so "Dffire" vs "Office" scores low.
Reversing both strings makes the suffix bonus kick in instead.
Test: max(JW, reverse_JW) as the base score.
"""

import re
import unicodedata
from rapidfuzz.distance import JaroWinkler
from harness import evaluate

PUNCT_RE = re.compile(r'^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$')

def strip_punct(t):
    return PUNCT_RE.sub('', t)

def norm(t):
    return strip_punct(unicodedata.normalize("NFKC", t)).lower()

def length_ratio(a, b):
    la, lb = len(a), len(b)
    if la == 0 or lb == 0:
        return 0.0
    return min(la, lb) / max(la, lb)


# --- Variants ---

def score_rev_jw_only(query, candidate):
    """Just reverse JW, no forward."""
    q, c = norm(query), norm(candidate)
    if not q or not c:
        return 0.0
    return JaroWinkler.similarity(q[::-1], c[::-1])

def score_max_jw_rev(query, candidate):
    """Max of forward JW and reverse JW."""
    q, c = norm(query), norm(candidate)
    if not q or not c:
        return 0.0
    fwd = JaroWinkler.similarity(q, c)
    rev = JaroWinkler.similarity(q[::-1], c[::-1])
    return max(fwd, rev)

def score_max_jw_rev_len(query, candidate):
    """Max(JW, rev_JW) * length penalty."""
    q, c = norm(query), norm(candidate)
    if not q or not c:
        return 0.0
    fwd = JaroWinkler.similarity(q, c)
    rev = JaroWinkler.similarity(q[::-1], c[::-1])
    lr = length_ratio(q, c)
    return max(fwd, rev) * (0.8 + 0.2 * lr)


if __name__ == "__main__":
    evaluate(score_rev_jw_only, name="15a - Reverse JW only")
    evaluate(score_max_jw_rev, name="15b - Max(JW, Reverse JW)")
    evaluate(score_max_jw_rev_len, name="15c - Max(JW, Rev JW) * len")
