"""Elegir de una lista por voz, y buscar dentro de un fichero (Ctrl+F).

La capa que le faltaba a las acciones de fichero. Buscar y soltar el primer
resultado no sirve cuando hay varios: hace falta enseñar la lista y poder decir
"abre el tercero". Y para buscar DENTRO de un fichero como con Ctrl+F, hace
falta recordar cual era.

Aqui va la logica pura —interpretar "el tercero", detectar las ordenes de
seleccion y de busqueda interna—; el estado (la ultima lista, el ultimo
fichero) y la ejecucion viven en el panel.
"""
import re

# Como se dice cada posicion. Se aceptan el ordinal, el numero en palabra y la
# cifra, porque el reconocedor devuelve cualquiera de los tres.
ORDINALES = {
    1: ["primero", "primera", "uno", "1"],
    2: ["segundo", "segunda", "dos", "2"],
    3: ["tercero", "tercera", "tres", "3"],
    4: ["cuarto", "cuarta", "cuatro", "4"],
    5: ["quinto", "quinta", "cinco", "5"],
    6: ["sexto", "sexta", "seis", "6"],
    7: ["septimo", "septima", "siete", "7"],
    8: ["octavo", "octava", "ocho", "8"],
    9: ["noveno", "novena", "nueve", "9"],
    10: ["decimo", "decima", "diez", "10"],
}
_PALABRA_A_N = {p: n for n, ps in ORDINALES.items() for p in ps}

# "el ultimo" es comodo y no es un numero
_ULTIMO = {"ultimo", "ultima", "final"}


def posicion(texto: str):
    """Devuelve el numero (1..N) que se ha dicho, -1 para 'el ultimo', o None.

    Se queda con la PRIMERA posicion mencionada, para que "abre el tercero"
    de 3 y no se lie con otros numeros que puedan venir detras.
    """
    for palabra in texto.split():
        if palabra in _ULTIMO:
            return -1
        if palabra in _PALABRA_A_N:
            return _PALABRA_A_N[palabra]
    return None


# Ordenes que actuan sobre la lista ya mostrada. El verbo dice que hacer con lo
# elegido; la posicion, cual.
_ABRIR = re.compile(r"\b(abre|abreme|abrir)\b")
_LEER = re.compile(r"\b(lee|leeme|leer|muestrame|ensename)\b")
_SELECCION = re.compile(r"\b(el|la|numero|opcion|resultado)\b")


def orden_de_seleccion(texto: str):
    """(accion, posicion) si el texto elige de la lista, o None.

    accion: "abrir" o "leer". posicion: 1..N o -1 (ultimo).
    Ejemplos: "abre el tercero", "lee el numero dos", "el ultimo", "abre el 3".
    """
    pos = posicion(texto)
    if pos is None:
        return None
    # tiene que sonar a seleccion, no a otra cosa que lleve un numero
    if not (_SELECCION.search(texto) or _ABRIR.search(texto) or _LEER.search(texto)):
        return None
    if _LEER.search(texto):
        return ("leer", pos)
    # por defecto, elegir es abrir
    return ("abrir", pos)


# Ctrl+F: buscar un termino dentro del ultimo fichero abierto.
_DENTRO = re.compile(
    r"\b(busca|buscame|encuentra)\b.*\b(dentro|en el fichero|en el archivo|en el texto)\b")


def orden_buscar_dentro(texto: str):
    """El termino a buscar dentro del fichero, o None.

    "busca dentro configuracion", "busca en el texto la palabra error".
    Se queda con lo que va despues de 'dentro'/'en el ...'.
    """
    if not _DENTRO.search(texto):
        return None
    # cortar por el separador y quedarse con el resto
    for sep in ("dentro de", "dentro", "en el fichero", "en el archivo", "en el texto",
                "la palabra"):
        if sep in texto:
            resto = texto.split(sep, 1)[1].strip()
            resto = re.sub(r"^(la palabra|el termino|de|la|el|los|las)\s+",
                           "", resto).strip()
            if resto:
                return resto
    return None
