"""Que preguntar cuando falta un dato para ejecutar una accion.

Pulsar una accion en el panel no puede limitarse a recitar la frase que la
dispara —"diga «busca el fichero» y a continuacion lo que busca"—: eso es un
manual de instrucciones, y uno pulsa justo porque no quiere leerse el manual.
Lo natural es que pregunte lo que falta y lo haga.

    busca el fichero            ->  ¿Que fichero, señor?
    manda la ventana a la pantalla ->  ¿A que pantalla, señor?
    mata el proceso            ->  ¿Que proceso, señor?

## Como sale la pregunta

Del propio catalogo, no de una lista escrita a mano ni de un modelo. Las frases
del catalogo son regulares —verbo + articulo + objeto— asi que basta con buscar
el ULTIMO articulo y quedarse con lo que va detras.

Y se pregunta por el OBJETO, no conjugando el verbo. "¿Que fichero, señor?" es
tan natural como "¿Que fichero busco, señor?" y no obliga a conjugar: pasar de
"busca" a "busco", de "leeme" a "leo" o de "pon" a "pongo" pide un diccionario
de verbos irregulares para ganar nada.

Si la preposicion viene delante del articulo, se conserva: sin ella, "manda la
ventana a la pantalla" preguntaria "¿Que pantalla?" y se pierde el "a", que es
justo lo que dice que la respuesta es un destino.
"""
import re
import unicodedata

ARTICULOS = {"el", "la", "los", "las", "un", "una", "unos", "unas"}
# Las contracciones ya llevan la preposicion dentro.
CONTRACCIONES = {"al": "a", "del": "de"}
PREPOSICIONES = {"a", "de", "en", "con", "por", "para", "sobre", "hacia", "desde"}

# Cuando no hay de donde sacarlo. Vale para "esta corriendo" o "tengo instalado",
# donde el objeto no aparece en la frase.
GENERICA = "¿El que, señor?"


def _sin_tildes(t: str) -> str:
    t = unicodedata.normalize("NFD", t)
    return "".join(c for c in t if unicodedata.category(c) != "Mn")


def pregunta_por(accion) -> str:
    """La pregunta que rellena el hueco de una accion que espera argumento.

    La clave: el argumento va SIEMPRE al final de la frase, porque asi lo
    recoge el emparejador. Asi que la pregunta se decide mirando como TERMINA.
    """
    frases = getattr(accion, "frases", None) or []
    if not frases:
        return GENERICA

    palabras = _sin_tildes(frases[0].lower()).split()
    if not palabras:
        return GENERICA
    ultima = palabras[-1]

    # 1. Termina en preposicion: el hueco va justo detras.
    #    "busca el precio de"  ->  ¿El precio de que, señor?
    #    "busca imagenes de"   ->  ¿Imagenes de que, señor?
    if ultima in PREPOSICIONES:
        trozo = []
        # Sin la primera palabra: es el verbo, y en la pregunta sobra.
        # "busca imagenes de" tiene que dar "¿Imagenes de que?", no
        # "¿Busca imagenes de que?".
        for p in reversed(palabras[1:-1]):
            if p in ARTICULOS or p in CONTRACCIONES:
                trozo.insert(0, p)
                break
            if p in PREPOSICIONES:
                break
            trozo.insert(0, p)
            if len(trozo) >= 2:
                break
        if trozo:
            frase = " ".join(trozo).capitalize()
            return f"¿{frase} {ultima} que, señor?"
        return GENERICA

    # 2. "busca en <sitio>": lo que falta es QUE buscar, no el sitio.
    #    Sin esta regla, "busca en la wikipedia" preguntaba "¿En que
    #    wikipedia?", que no tiene sentido: solo hay una.
    if "en" in palabras:
        i = palabras.index("en")
        sitio = " ".join(palabras[i:])
        verbo = palabras[0]
        if verbo.startswith("busca"):
            return f"¿Que busco {sitio}, señor?"
        return f"¿Que {sitio}, señor?"

    # 3. Lo normal: articulo + objeto al final.
    #    "busca el fichero"             ->  ¿Que fichero, señor?
    #    "manda la ventana a la pantalla" -> ¿A que pantalla, señor?
    for i in range(len(palabras) - 1, -1, -1):
        p = palabras[i]
        objeto = palabras[i + 1] if i + 1 < len(palabras) else ""
        if not objeto:
            continue
        if p in CONTRACCIONES:
            return f"¿{CONTRACCIONES[p].capitalize()} que {objeto}, señor?"
        if p in ARTICULOS:
            anterior = palabras[i - 1] if i > 0 else ""
            if anterior in PREPOSICIONES:
                return f"¿{anterior.capitalize()} que {objeto}, señor?"
            return f"¿Que {objeto}, señor?"
    return GENERICA


def confirmacion(accion) -> str:
    """Lo que se pregunta antes de algo que no tiene vuelta atras.

    La orden se CITA en vez de meterla en la frase. Las del catalogo estan en
    imperativo —"cierra el navegador"— y encajarlas da cosas como "Voy a cierra
    el navegador". Conjugarlas al infinitivo pediria un diccionario de verbos
    irregulares (cierra->cerrar, pon->poner, ve->ir) para ganar poco: entre
    comillas se lee bien y ademas queda claro que es literalmente la orden.
    """
    frase = (getattr(accion, "frases", None) or [""])[0]
    return f"«{frase}». Esto no tiene vuelta atras. ¿Confirma, señor?"


# Lo que cuenta como si y como no. Se comparan sin tildes y sin puntuacion,
# porque llegan de Whisper: "sí", "Si.", "SÍ" y "sip" son lo mismo.
SI = {"si", "sip", "claro", "vale", "venga", "adelante", "confirmo", "hazlo",
      "por supuesto", "correcto", "afirmativo", "eso es", "dale", "ok", "okey"}
NO = {"no", "nop", "nada", "dejalo", "olvidalo", "cancela", "cancelalo",
      "para", "mejor no", "negativo", "ni hablar", "espera"}


def es_si(texto: str):
    """True si es un si, False si es un no, None si no es ni una cosa ni otra."""
    limpio = _sin_tildes(re.sub(r"[¡!¿?.,;]", "", (texto or "").lower())).strip()
    if not limpio:
        return None
    if limpio in SI:
        return True
    if limpio in NO:
        return False
    # Tambien al principio: "si, hazlo" o "no, dejalo"
    primera = limpio.split()[0]
    if primera in SI:
        return True
    if primera in NO:
        return False
    return None
