"""
candy.conversation — Gestionnaire de conversations multi-tours
==============================================================

Permet de maintenir un historique de conversation avec une personnalité.

Exemple :
    from candy import Conversation, Coding, cfg

    cfg.A.lang = "FR"

    chat = Conversation(Coding, profile="A")
    print(chat.say("Explique les décorateurs Python"))
    print(chat.say("Donne-moi un exemple avec une classe"))
    print(chat.say("Et avec des arguments ?"))

    chat.show_history()   # affiche l'historique
    chat.clear()          # efface l'historique
    chat.save("chat.json")  # sauvegarde
    chat.load("chat.json")  # charge
"""

import json
from typing import Optional
from .client import _client
from .config import get_profile


class Conversation:
    """
    Gestionnaire de conversation multi-tours avec une personnalité candy.

    Mémorise l'historique et l'envoie à chaque requête pour garder le contexte.
    """

    def __init__(self, module, profile: str = "default", max_history: int = 20):
        """
        Args:
            module:      Personnalité candy (ex: Coding, Math, Full...)
            profile:     Nom du profil à utiliser (défaut: "default")
            max_history: Nombre max d'échanges mémorisés (défaut: 20)
        """
        self._personality = module._personality
        self._profile_name = profile
        self._max_history = max_history
        self._history: list = []

    # ── Conversation ─────────────────────────────────────────────────────────

    def say(self, prompt: str, context: Optional[str] = None) -> str:
        """
        Envoie un message et retourne la réponse.
        L'historique est automatiquement maintenu.
        """
        profile = get_profile(self._profile_name)
        result = _client.ask(
            self._personality, prompt, profile,
            context=context, stream=False,
            history=self._history if self._history else None
        )
        response = result.get("response", "")

        # Mémorise l'échange
        self._history.append({"role": "user",      "content": prompt})
        self._history.append({"role": "assistant",  "content": response})

        # Tronque l'historique si trop long
        if len(self._history) > self._max_history * 2:
            self._history = self._history[-(self._max_history * 2):]

        return response

    def stream_say(self, prompt: str, context: Optional[str] = None):
        """Envoie un message et streame la réponse token par token."""
        import sys
        profile = get_profile(self._profile_name)
        tokens = []
        gen = _client.ask(
            self._personality, prompt, profile,
            context=context, stream=True,
            history=self._history if self._history else None
        )
        for token in gen:
            sys.stdout.write(token)
            sys.stdout.flush()
            tokens.append(token)
        sys.stdout.write("\n")
        response = "".join(tokens)
        self._history.append({"role": "user",     "content": prompt})
        self._history.append({"role": "assistant", "content": response})
        return response

    # ── Historique ───────────────────────────────────────────────────────────

    def clear(self):
        """Efface l'historique de conversation."""
        self._history = []

    def show_history(self):
        """Affiche l'historique dans le terminal."""
        if not self._history:
            print("\033[90m[candy] Historique vide.\033[0m")
            return
        print(f"\033[95m🍬 Historique — {self._personality} [{self._profile_name}]\033[0m")
        for msg in self._history:
            role  = msg["role"]
            color = "\033[97m" if role == "user" else "\033[96m"
            label = "Vous     " if role == "user" else "candy    "
            print(f"{color}{label}\033[0m {msg['content'][:120]}{'...' if len(msg['content']) > 120 else ''}")

    def get_history(self) -> list:
        """Retourne l'historique brut."""
        return list(self._history)

    def count_turns(self) -> int:
        """Retourne le nombre de tours de conversation."""
        return len(self._history) // 2

    # ── Sauvegarde / chargement ──────────────────────────────────────────────

    def save(self, path: str):
        """Sauvegarde l'historique dans un fichier JSON."""
        data = {
            "personality": self._personality,
            "profile":     self._profile_name,
            "history":     self._history,
        }
        with open(path, "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
        print(f"\033[90m[candy] Historique sauvegardé → {path}\033[0m")

    def load(self, path: str):
        """Charge un historique depuis un fichier JSON."""
        with open(path, "r", encoding="utf-8") as f:
            data = json.load(f)
        self._history = data.get("history", [])
        print(f"\033[90m[candy] Historique chargé ← {path} ({self.count_turns()} tours)\033[0m")

    def __repr__(self):
        return (f"<Conversation personality={self._personality!r} "
                f"profile={self._profile_name!r} turns={self.count_turns()}>")
