"""
candy.helper — Agent Helper v9
================================
Helper génère du code candy-ai GARANTI via templates prédéfinis.
Aucune génération libre — 100% candy, jamais de librairies externes.

UTILISATION :
    from candy import Helper

    Helper.list()                                    # voir les templates
    code = Helper.write("livre", sujet="Napoléon", lang="FR", chapitres=20)
    code = Helper.write("traduction", texte="Bonjour", langues=["ES","DE","JA"])
    code = Helper.write("chatbot", lang="FR")
    code = Helper.write("pipeline", tache="analyser un contrat", lang="FR")
    code = Helper.write("batch", questions=["Q1","Q2","Q3"], module="Math")
    code = Helper.write("résumé", lang="FR")
    code = Helper.write("question", module="History", lang="FR")

    Helper.preview("livre", sujet="La Révolution française", lang="FR")
    Helper.run("chatbot", lang="FR")
"""

from typing import Optional


def _build_livre(sujet: str = "la Seconde Guerre mondiale",
                 lang: str = "FR", chapitres: int = 20,
                 fichier: str = "output.md") -> str:
    return f'''from candy import cfg, Writing, Planner

# ── Profil ────────────────────────────────────────────────────────
cfg.p.lang          = "{lang}"
cfg.p.max_tokens    = 4096
cfg.p.style         = "detailed"
cfg.p.output_format = "markdown"
cfg.p.temperature   = 0.7
cfg.p.retry         = 2

# ── Génération du plan ────────────────────────────────────────────
print("📚 Génération du plan...")
plan = Planner.use("p").ask(
    "Crée un plan de {chapitres} chapitres pour un livre sur : {sujet}. "
    "Retourne UNIQUEMENT la liste numérotée des titres, un par ligne. "
    "Chaque ligne doit commencer par son numéro suivi d'un point."
)
print(plan)

# ── Extraction des chapitres ──────────────────────────────────────
chapitres = [l.strip() for l in plan.split("\\n")
             if l.strip() and l.strip()[0].isdigit()]

# ── Écriture chapitre par chapitre ────────────────────────────────
texte = "# {sujet}\\n\\n---\\n\\n"

for i, titre in enumerate(chapitres[:{chapitres}], 1):
    print(f"✍️  [{{i:02d}}/{chapitres}] {{titre}}")
    contenu = Writing.use("p").ask(
        f"Tu écris un livre en {lang} sur : {sujet}. "
        f"Écris le chapitre {{i}} intitulé : {{titre}}. "
        f"400 à 500 mots, factuel, bien structuré, pédagogique. "
        f"Commence DIRECTEMENT par le texte du chapitre sans répéter le titre."
    )
    texte += f"## Chapitre {{i}} — {{titre}}\\n\\n{{contenu}}\\n\\n---\\n\\n"

# ── Sauvegarde ────────────────────────────────────────────────────
with open("{fichier}", "w", encoding="utf-8") as f:
    f.write(texte)

print(f"\\n✅ Terminé ! {{len(chapitres)}} chapitres — {{len(texte):,}} caractères")
print(f"📄 Sauvegardé → {fichier}")
'''


def _build_traduction(texte: str = "Bonjour, comment allez-vous ?",
                      langues: list = None) -> str:
    if langues is None:
        langues = ["ES", "DE", "IT", "JA", "ZH"]
    noms = {
        "FR": "français", "EN": "anglais", "ES": "espagnol", "DE": "allemand",
        "IT": "italien", "PT": "portugais", "ZH": "chinois", "JA": "japonais",
        "AR": "arabe", "RU": "russe", "NL": "néerlandais", "PL": "polonais",
        "SV": "suédois", "TR": "turc", "KO": "coréen", "HI": "hindi",
    }
    lignes = []
    for code in langues:
        nom = noms.get(code.upper(), code)
        lignes.append(f'''    # → {nom}
    cfg.trad_{code}.lang       = "{code.upper()}"
    cfg.trad_{code}.max_tokens = 300
    cfg.trad_{code}.style      = "concise"
    result_{code} = Translator.use("trad_{code}").ask(
        f"Traduis ce texte en {nom}, retourne UNIQUEMENT la traduction : {texte}"
    )
    print(f"[{code.upper()}] {{result_{code}}}")''')

    corps = "\n\n".join(lignes)
    imports_cfg = "\n".join([f"from candy import cfg, Translator"])
    return f'''{imports_cfg}

texte_original = "{texte}"
print(f"Original : {{texte_original}}\\n")

{corps}
'''


def _build_chatbot(lang: str = "FR", module: str = "Full",
                   style: str = "casual", tone: str = "encouraging") -> str:
    return f'''from candy import cfg, {module}, Conversation

# ── Profil ────────────────────────────────────────────────────────
cfg.chat.lang  = "{lang}"
cfg.chat.style = "{style}"
cfg.chat.tone  = "{tone}"
cfg.chat.max_tokens = 1024

# ── Session de conversation ───────────────────────────────────────
session = Conversation({module}, profile="chat", max_history=20)

print("🍬 Candy Chatbot ({module}) — tape \\'quitter\\' pour arrêter\\n")

while True:
    user_input = input("Vous : ").strip()
    if not user_input:
        continue
    if user_input.lower() in ("quitter", "exit", "quit", "q"):
        print("Au revoir !")
        break
    reponse = session.say(user_input)
    print(f"\\nCandy : {{reponse}}\\n")
'''


def _build_pipeline(tache: str = "analyser un texte",
                    lang: str = "FR") -> str:
    return f'''from candy import cfg, Coding, Debugger, Reviewer

# ── Profil ────────────────────────────────────────────────────────
cfg.dev = cfg.preset("coder")
cfg.dev.lang = "{lang}"
cfg.dev.retry = 2

# ── Pipeline : génération → debug → review ────────────────────────
print("⚙️  Étape 1 — Génération...")
code = Coding.use("dev").ask(
    "Écris le code Python pour : {tache}"
)
print(code)

print("\\n🐛 Étape 2 — Détection de bugs...")
bugs = Debugger.use("dev").ask(
    "Analyse ce code et liste les bugs ou problèmes potentiels :",
    context=code
)
print(bugs)

print("\\n✅ Étape 3 — Revue qualité...")
review = Reviewer.use("dev").ask(
    "Évalue la qualité, lisibilité et les bonnes pratiques de ce code :",
    context=code
)
print(review)
'''


def _build_batch(questions: list = None, module: str = "Full",
                 lang: str = "FR") -> str:
    if questions is None:
        questions = ["Qu'est-ce que Python ?",
                     "Qu'est-ce qu'une liste ?",
                     "Qu'est-ce qu'un dictionnaire ?"]
    qs = repr(questions)
    return f'''from candy import cfg, {module}

# ── Profil ────────────────────────────────────────────────────────
cfg.b.lang       = "{lang}"
cfg.b.max_tokens = 300
cfg.b.style      = "concise"

# ── Questions ─────────────────────────────────────────────────────
questions = {qs}

print(f"📦 Batch de {{len(questions)}} questions vers {module}\\n")

reponses = {module}.use("b").batch(questions)

for i, (q, r) in enumerate(zip(questions, reponses), 1):
    print(f"[{{i}}] Q: {{q}}")
    print(f"    R: {{r}}")
    print()
'''


def _build_resume(lang: str = "FR", fichier_sortie: str = "resume.md") -> str:
    return f'''from candy import cfg, Summarizer

# ── Profil ────────────────────────────────────────────────────────
cfg.s.lang       = "{lang}"
cfg.s.max_tokens = 600
cfg.s.style      = "bullet"
cfg.s.output_format = "markdown"

# ── Texte à résumer ───────────────────────────────────────────────
print("Colle ton texte à résumer (termine avec une ligne vide + Entrée) :")
lignes = []
while True:
    ligne = input()
    if ligne == "":
        break
    lignes.append(ligne)

texte = "\\n".join(lignes)

if not texte.strip():
    print("Aucun texte fourni.")
else:
    print("\\n📝 Résumé en cours...\\n")
    resume = Summarizer.use("s").ask(
        "Fais un résumé structuré de ce texte en points clés :",
        context=texte
    )
    print(resume)

    with open("{fichier_sortie}", "w", encoding="utf-8") as f:
        f.write(f"# Résumé\\n\\n{{resume}}")
    print(f"\\n💾 Sauvegardé → {fichier_sortie}")
'''


def _build_question(module: str = "Full", lang: str = "FR",
                    style: str = "detailed") -> str:
    return f'''from candy import cfg, {module}

# ── Profil ────────────────────────────────────────────────────────
cfg.q.lang       = "{lang}"
cfg.q.max_tokens = 1024
cfg.q.style      = "{style}"
cfg.q.tone       = "neutral"

# ── Question ──────────────────────────────────────────────────────
question = input("Votre question : ").strip()

if question:
    print("\\n⏳ Réponse en cours...\\n")
    reponse = {module}.use("q").ask(question)
    print(reponse)
else:
    print("Aucune question fournie.")
'''


# ── Registre des templates ───────────────────────────────────────────────────
_REGISTRY = {
    "livre":       ("Générer un livre de N chapitres sur un sujet",         _build_livre),
    "traduction":  ("Traduire un texte vers plusieurs langues",             _build_traduction),
    "chatbot":     ("Chatbot interactif en boucle",                         _build_chatbot),
    "pipeline":    ("Pipeline Coding → Debugger → Reviewer",               _build_pipeline),
    "batch":       ("Envoyer plusieurs questions d'un coup",                _build_batch),
    "résumé":      ("Résumer un texte collé dans le terminal",              _build_resume),
    "question":    ("Poser une question à une personnalité",                _build_question),
}


class _Helper:
    """
    Agent candy v9 — génère du code Python candy-ai via templates garantis.
    Le code généré utilise TOUJOURS candy et uniquement candy.

    Méthodes :
        Helper.list()              → liste les templates disponibles
        Helper.write(template, **kwargs) → retourne le code (str)
        Helper.preview(template, **kwargs) → affiche le code numéroté
        Helper.run(template, **kwargs)     → génère ET exécute
    """

    def list(self):
        """Affiche tous les templates disponibles."""
        print("\033[95m🍬 Helper v9 — Templates disponibles :\033[0m\n")
        for name, (desc, _) in _REGISTRY.items():
            print(f"  \033[96m{name:12s}\033[0m — {desc}")
        print("\n\033[90mUsage : Helper.write('template', param=valeur, ...)\033[0m")
        print("\033[90mEx    : Helper.write('livre', sujet='Napoléon', lang='FR', chapitres=20)\033[0m")

    def write(self, template: str, **kwargs) -> str:
        """
        Génère du code candy pour le template demandé.

        Templates : livre, traduction, chatbot, pipeline, batch, résumé, question

        Args (selon template) :
            livre      : sujet, lang, chapitres, fichier
            traduction : texte, langues (liste de codes)
            chatbot    : lang, module, style, tone
            pipeline   : tache, lang
            batch      : questions (liste), module, lang
            résumé     : lang, fichier_sortie
            question   : module, lang, style

        Returns:
            Code Python candy prêt à être exécuté.
        """
        key = template.lower().strip()
        # Accepte "resume" sans accent
        if key == "resume":
            key = "résumé"
        if key not in _REGISTRY:
            available = ", ".join(_REGISTRY.keys())
            return f"# Template inconnu : '{template}'\n# Disponibles : {available}"
        _, builder = _REGISTRY[key]
        try:
            return builder(**kwargs)
        except TypeError as e:
            return f"# Paramètre manquant ou incorrect : {e}"

    def preview(self, template: str, **kwargs) -> str:
        """Affiche le code numéroté et coloré sans l'exécuter."""
        code = self.write(template, **kwargs)
        print("\033[95m╔══ Helper — Code candy v9 ════════════════════════╗\033[0m")
        for i, line in enumerate(code.split("\n"), 1):
            print(f"\033[90m{i:3d}\033[0m  \033[96m{line}\033[0m")
        print("\033[95m╚══════════════════════════════════════════════════╝\033[0m")
        return code

    def run(self, template: str, **kwargs):
        """Génère le code candy et l'exécute directement."""
        code = self.write(template, **kwargs)
        self.preview(code if "\nfrom candy" in code else template, **({} if "\nfrom candy" in code else kwargs))
        print("\033[90m[Helper] Exécution...\033[0m\n")
        try:
            exec(code, {"__name__": "__main__"})
        except Exception as e:
            print(f"\033[91m[Helper] Erreur : {e}\033[0m")

    def __repr__(self):
        return "<candy.Helper v9 — 7 templates candy garantis>"


Helper = _Helper()
