"""
Typo generator for Trend Surfer / brand typos.

No external APIs.
"""

from __future__ import annotations

import string


KEYBOARD_NEIGHBORS = {
    # simplified QWERTY adjacency (enough for useful typos)
    "q": "wa",
    "w": "qase",
    "e": "wsdr",
    "r": "edft",
    "t": "rfgy",
    "y": "tghu",
    "u": "yhji",
    "i": "ujko",
    "o": "iklp",
    "p": "ol",
    "a": "qwsz",
    "s": "awedxz",
    "d": "serfcx",
    "f": "drtgvc",
    "g": "ftyhbv",
    "h": "gyujbn",
    "j": "huikmn",
    "k": "jiolm",
    "l": "kop",
    "z": "asx",
    "x": "zsdc",
    "c": "xdfv",
    "v": "cfgb",
    "b": "vghn",
    "n": "bhjm",
    "m": "njk",
}


def _normalize_brand(brand: str) -> str:
    b = (brand or "").lower().strip()
    b = "".join(ch for ch in b if ch in string.ascii_lowercase)
    return b


def generate_typos(brand: str, *, limit: int = 100) -> list[str]:
    b = _normalize_brand(brand)
    if len(b) < 2:
        return []

    candidates: list[str] = []
    seen = set()

    def _add(s: str):
        if s and s not in seen and s != b:
            seen.add(s)
            candidates.append(s)

    # 1) single deletion
    for i in range(len(b)):
        _add(b[:i] + b[i + 1 :])
        if len(candidates) >= limit:
            return candidates

    # 2) single insertion (duplicate char)
    for i in range(len(b)):
        _add(b[:i] + b[i] + b[i:])
        if len(candidates) >= limit:
            return candidates

    # 3) adjacent transposition
    for i in range(len(b) - 1):
        _add(b[:i] + b[i + 1] + b[i] + b[i + 2 :])
        if len(candidates) >= limit:
            return candidates

    # 4) neighbor substitution
    for i, ch in enumerate(b):
        neigh = KEYBOARD_NEIGHBORS.get(ch, "")
        for n in neigh:
            _add(b[:i] + n + b[i + 1 :])
            if len(candidates) >= limit:
                return candidates

    return candidates[:limit]

