"""Baseline: aggressive shape compression (~25 classes) + Levenshtein."""

import unicodedata
from rapidfuzz import fuzz
from harness import evaluate

# Multi-char rewrites applied before shape mapping
MULTI_CHAR_RULES = [
    ("rn", "m"),
    ("nn", "m"),
    ("ri", "n"),
    ("cl", "d"),
    ("vv", "w"),
    ("ii", "u"),
]
MULTI_CHAR_RULES.sort(key=lambda x: len(x[0]), reverse=True)

# Shape classes: map every character to a visual equivalence class
# Philosophy: optimize for recall (stage 1 filter), precision comes later
SHAPE_MAP = {}

# Vertical strokes: i l 1 I | ! t f j
for ch in "il1I|!tfj":
    SHAPE_MAP[ch] = "I"

# Round/oval: o O 0 c C e Q a
for ch in "oO0cCeQa":
    SHAPE_MAP[ch] = "O"

# Wide humps: m w M W
for ch in "mwMW":
    SHAPE_MAP[ch] = "M"

# Single hump: n u v N U V
for ch in "nuvNUV":
    SHAPE_MAP[ch] = "N"

# Ascender loops: b h k 6
for ch in "bhk6":
    SHAPE_MAP[ch] = "B"

# Descender loops: p q g y 9
for ch in "pqgy9":
    SHAPE_MAP[ch] = "P"

# Right-facing bowls: d D P R B
for ch in "dDPRB":
    SHAPE_MAP[ch] = "D"

# Diagonals: x X z Z K
for ch in "xXzZK":
    SHAPE_MAP[ch] = "X"

# S-snakes: s S 5 $
for ch in "sS5$":
    SHAPE_MAP[ch] = "S"

# Horizontals: - _ ~ =
for ch in "-_~=":
    SHAPE_MAP[ch] = "H"

# Digits not yet mapped
for ch in "234":
    SHAPE_MAP[ch] = "2"
for ch in "78":
    SHAPE_MAP[ch] = "7"

# r stays as r (common, distinct enough)
SHAPE_MAP["r"] = "R"


def shape_compress(text):
    text = unicodedata.normalize("NFKC", text)
    text = text.lower()
    # Apply multi-char rules first
    for pattern, replacement in MULTI_CHAR_RULES:
        text = text.replace(pattern, replacement)
    # Map to shape classes
    result = []
    for ch in text:
        if ch.isspace():
            result.append(" ")
        else:
            result.append(SHAPE_MAP.get(ch, ch))
    return "".join(result)


def score(query, candidate):
    q = shape_compress(query)
    c = shape_compress(candidate)
    return fuzz.ratio(q, c) / 100.0


if __name__ == "__main__":
    evaluate(score, name="07 - Shape Compression + Levenshtein")
