# -*- coding: utf-8 -*-
"""French -> English hover translations for every French string in the curriculum.

Order of lookup: hand-written sentences (en_sentences.SENT) -> templates for generated instructions ->
article + word from the lexicon -> lexicon. build() returns {normalised French: English}; missing() lists gaps."""
import re
from .en_lexicon import LEX
from .en_sentences import SENT
try:
    from .en_machine import MACHINE      # local-model translations (tools/translate_en.py), used last
except ImportError:
    MACHINE = {}

NAMES = {"Anna", "Bob", "Carla", "David", "René", "Frida", "Galina", "Hervé", "Irène", "Jill", "Kira", "Luc", "Marie", "Nicole", "Oscar",
         "Pamela", "Quentin", "Robin", "Samia", "Tom", "Ursula", "Victor", "Wendy", "Xavier", "Yasmina", "Zoé", "Bruno", "Annie", "Mistou",
         "Simone", "Émilie", "Yaseen", "Madame Simone", "Madame Émilie", "Madame Rose"}

ART = {"un": "a", "une": "a", "le": "the", "la": "the", "l'": "the", "les": "the", "des": "some", "deux": "two", "il": "he", "elle": "she"}

T = [  # (regex, English template)
    (r"J'observe, j'écoute et je retiens", "I look, I listen and I remember"),
    (r"J'entoure les (\w) \((\w)\)", r"I circle the letters \1 (\2)"),
    (r"Je touche toutes les lettres (\w) et (\w)\.", r"I tap all the letters \1 and \2."),
    (r"Je colorie les (\w) en rouge et les (\w) en vert", r"I colour the \1 red and the \2 green"),
    (r"Les (\w) \((\w)\) en rouge, les (\w) \((\w)\) en vert\.", r"The \1 (\2) in red, the \3 (\4) in green."),
    (r"J'entoure les images qui contiennent le son (\w)", r"I circle the pictures that contain the sound \1"),
    (r"Je touche les images qui contiennent le son (\w)\.", r"I tap the pictures that contain the sound \1."),
    (r"Je complète avec (\w) \((\w)\) ou (\w) \((\w)\)", r"I complete with \1 (\2) or \3 (\4)"),
    (r"Je choisis la bonne lettre : (\w) ou (\w)\.", r"I choose the right letter: \1 or \2."),
    (r"Je m'amuse : j'entoure la lettre (\w) dans les mots", r"Fun time: I circle the letter \1 in the words"),
    (r"J'entoure la lettre (\w) dans les mots", r"I circle the letter \1 in the words"),
    (r"Je touche la lettre (\w) dans chaque mot illustré\.", r"I tap the letter \1 in each picture word."),
    (r"Je touche la lettre (\w) dans chaque mot\.", r"I tap the letter \1 in each word."),
    (r"Je trace (\w) (\w) (\w) (\w) avec mon doigt\.", r"I trace \1 \2 \3 \4 with my finger."),
    (r"Les lettres (\w) et (\w)", r"The letters \1 and \2"),
    (r"Bilan : L'alphabet (\w) – (\w)", r"Review: the alphabet \1 – \2"),
    (r"L'alphabet (\w) – (\w)", r"The alphabet \1 – \2"),
    (r"([A-Za-z]) ([A-Za-z])", r"the letter \1 \2"),
    (r"Je chante : (.+)", r"I sing: \1"),
    (r"« (.+) » veut dire :", r"« \1 » means:"),
]


def norm(s):
    s = s.replace("’", "'").replace("🔊", "")
    s = re.sub(r"[\U0001F000-\U0001FFFF\u2600-\u27BF\uFE0F\u200D]", "", s)
    return re.sub(r"\s+", " ", s).strip()


def lookup(s):
    k = norm(s)
    if not k:
        return None
    if k in SENT:
        return SENT[k]
    if k.rstrip(".") in NAMES:
        return k.rstrip(".") + " (a name)"
    if re.fullmatch(r"[\d\s]+", k):
        return k
    for rx, en in T:
        if re.fullmatch(rx, k):
            return re.sub(rx, en, k)
    low = k.lower().rstrip(" !?.")
    if low in LEX:
        return LEX[low]
    m = re.match(r"^(une|un|les|le|la|des|deux|il|elle) (.+)$", low) or re.match(r"^(l')(.+)$", low)
    if m and m.group(2) in LEX:
        return ART[m.group(1)] + " " + LEX[m.group(2)]
    m = re.match(r"^___ (.+)$", low)
    if m and m.group(1) in LEX:
        return "___ " + LEX[m.group(1)]
    return MACHINE.get(k)


def strings(units):
    keys = {"desc_fr", "title", "instr", "text", "fr", "q", "prompt", "answer", "word", "rule", "label", "rtext", "choices", "bank", "words"}
    out = set()

    def walk(o, k=None):
        if isinstance(o, dict):
            for kk, v in o.items():
                walk(v, kk)
        elif isinstance(o, list):
            for v in o:
                walk(v, k)
        elif isinstance(o, str) and k in keys and not o.endswith("_c") and not re.search(r"[\u0600-\u06FF]", o) and len(o) > 1:
            out.add(norm(o))
    walk(units)
    return out


def build(units):
    en = {}
    for s in strings(units):
        t = lookup(s)
        if t:
            en[s] = t
    return en


def missing(units):
    return sorted(s for s in strings(units) if not lookup(s))
