"""Convierte un nombre/titulo de Obsidian a un slug kebab-case estable.

Funcion pura: transliteracion Unicode + normalizacion a [a-z0-9-]. No hace I/O.
"""

import re
import unicodedata

# Cualquier secuencia de caracteres que NO sea [a-z0-9] colapsa a un solo '-'.
_NON_SLUG_RE = re.compile(r"[^a-z0-9]+")

# Mapeo explicito de caracteres que NFKD no descompone como queremos.
_TRANSLIT_MAP = {
    "ñ": "n",
    "Ñ": "n",
}


def slugify_obsidian_name(name: str) -> str:
    """Convierte un nombre o titulo a un slug kebab-case estable.

    Pasos, en orden:
        1. Mapea caracteres especiales que NFKD no descompone (ñ/Ñ -> n).
        2. Normaliza con ``unicodedata.normalize('NFKD', ...)`` y descarta los
           combining marks (acentos, diacriticos), transliterando a ASCII.
        3. Pasa todo a minusculas.
        4. Reemplaza cualquier secuencia de caracteres no ``[a-z0-9]`` por un
           unico ``-``.
        5. Hace strip de ``-`` al inicio y al final. Nunca quedan guiones dobles.

    Es deterministica y pura: misma entrada -> mismo slug, sin efectos
    secundarios ni I/O.

    Args:
        name: Nombre o titulo arbitrario (puede llevar acentos, mayusculas,
            espacios, simbolos).

    Returns:
        El slug kebab-case correspondiente. Cadena vacia si ``name`` no
        contiene ningun caracter slugificable.
    """
    if not name:
        return ""

    # 1. Mapeo explicito antes de NFKD (la cedilla de la enye se trataria mal).
    for src, dst in _TRANSLIT_MAP.items():
        name = name.replace(src, dst)

    # 2. Transliteracion Unicode: descompone y descarta combining marks.
    decomposed = unicodedata.normalize("NFKD", name)
    ascii_only = "".join(ch for ch in decomposed if not unicodedata.combining(ch))

    # 3. Minusculas.
    lowered = ascii_only.lower()

    # 4. Colapsar todo lo no [a-z0-9] a un unico '-'.
    slug = _NON_SLUG_RE.sub("-", lowered)

    # 5. Strip de guiones en los bordes.
    return slug.strip("-")


if __name__ == "__main__":
    assert slugify_obsidian_name("Enmanuel Gutiérrez Pérez") == "enmanuel-gutierrez-perez"
    assert slugify_obsidian_name("Jose manuel camaño castro") == "jose-manuel-camano-castro"
    assert slugify_obsidian_name("DNI de María del Mar") == "dni-de-maria-del-mar"
    assert slugify_obsidian_name("  raro__nombre!! ") == "raro-nombre"
    assert slugify_obsidian_name("") == ""
    assert slugify_obsidian_name("!!!") == ""
    print("slugify_obsidian_name smoke OK")
