"""
candy.auto_memory — Mémoire inter-sessions automatique (v21)
=============================================================

candy se souvient automatiquement des préférences de l'utilisateur
entre les conversations, sans rechargement manuel.

Usage :
    from candy import AutoMemory, Coding

    # Active la mémoire globale — persistée dans ~/.candy/user_memory.json
    AutoMemory.enable()

    # candy se souviendra que tu préfères le FR, le style concis, etc.
    chat = Coding.chat()
    chat.say("Je préfère toujours des réponses courtes en français")
    chat.say("J'utilise Python 3.12 et FastAPI")

    # La prochaine fois, candy s'en souvient automatiquement :
    chat2 = Coding.chat()
    # → répond déjà en FR, style concis, contexte Python/FastAPI

    # Voir ce que candy a mémorisé
    print(AutoMemory.summary())

    # Ajouter manuellement un fait
    AutoMemory.remember("Je travaille sur un projet de RAG avec ChromaDB")

    # Oublier tout
    AutoMemory.forget()

    # Désactiver
    AutoMemory.disable()
"""

import json
from pathlib import Path
from typing import Optional

_MEMORY_FILE = Path.home() / ".candy" / "user_memory.json"
_MAX_FACTS   = 30
_enabled     = False


def _load() -> dict:
    try:
        if _MEMORY_FILE.exists():
            return json.loads(_MEMORY_FILE.read_text(encoding="utf-8"))
    except Exception:
        pass
    return {"facts": [], "preferences": {}, "enabled": False}


def _save(data: dict):
    try:
        _MEMORY_FILE.parent.mkdir(parents=True, exist_ok=True)
        _MEMORY_FILE.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
    except Exception:
        pass


class _AutoMemory:
    """
    Gestionnaire de mémoire inter-sessions.
    Persistée dans ~/.candy/user_memory.json.
    """

    def enable(self):
        """Active la mémoire automatique."""
        global _enabled
        _enabled = True
        data = _load()
        data["enabled"] = True
        _save(data)
        print("\033[90m[candy] 🧠 AutoMemory activée — ~/.candy/user_memory.json\033[0m")

    def disable(self):
        """Désactive la mémoire automatique (sans effacer les données)."""
        global _enabled
        _enabled = False
        data = _load()
        data["enabled"] = False
        _save(data)
        print("\033[90m[candy] 🧠 AutoMemory désactivée.\033[0m")

    def is_enabled(self) -> bool:
        return _load().get("enabled", False)

    def remember(self, fact: str):
        """
        Ajoute manuellement un fait à la mémoire.

            AutoMemory.remember("Je travaille avec FastAPI et Python 3.12")
        """
        data = _load()
        if fact not in data["facts"]:
            data["facts"].append(fact)
            if len(data["facts"]) > _MAX_FACTS:
                data["facts"] = data["facts"][-_MAX_FACTS:]
            _save(data)
            print(f"\033[90m[candy] 🧠 Mémorisé : {fact[:80]}\033[0m")

    def forget(self, fact: Optional[str] = None):
        """
        Oublie un fait spécifique, ou tout si fact=None.

            AutoMemory.forget()                           # tout effacer
            AutoMemory.forget("Je travaille avec FastAPI") # effacer un fait
        """
        data = _load()
        if fact is None:
            data["facts"] = []
            data["preferences"] = {}
            print("\033[90m[candy] 🧠 Mémoire effacée.\033[0m")
        else:
            data["facts"] = [f for f in data["facts"] if fact.lower() not in f.lower()]
            print(f"\033[90m[candy] 🧠 Oublié : {fact}\033[0m")
        _save(data)

    def summary(self) -> dict:
        """
        Retourne un résumé de ce que candy a mémorisé.

            print(AutoMemory.summary())
        """
        data = _load()
        return {
            "enabled":     data.get("enabled", False),
            "facts":       data.get("facts", []),
            "preferences": data.get("preferences", {}),
            "fact_count":  len(data.get("facts", [])),
        }

    def as_context(self) -> str:
        """
        Retourne les faits mémorisés sous forme de contexte injectabel.
        Utilisé automatiquement par Conversation si AutoMemory est activée.
        """
        data = _load()
        facts = data.get("facts", [])
        prefs = data.get("preferences", {})
        if not facts and not prefs:
            return ""
        lines = ["[Contexte utilisateur mémorisé par candy :]"]
        for fact in facts[-15:]:  # 15 faits max injectés
            lines.append(f"  - {fact}")
        if prefs:
            for k, v in prefs.items():
                lines.append(f"  - Préférence {k}: {v}")
        return "\n".join(lines)

    def extract_from_message(self, message: str):
        """
        Tente d'extraire des préférences ou faits depuis un message utilisateur.
        Appelé automatiquement par Conversation.say() si AutoMemory est activée.
        """
        data    = _load()
        msg_low = message.lower()

        # Détection basique de préférences
        triggers = [
            ("je préfère", None),
            ("j'utilise", None),
            ("je travaille", None),
            ("je suis", None),
            ("mon projet", None),
            ("toujours en", None),
            ("i prefer", None),
            ("i use", None),
            ("i work", None),
        ]
        for trigger, _ in triggers:
            if trigger in msg_low and len(message) < 200:
                if message not in data["facts"]:
                    data["facts"].append(message)
                    if len(data["facts"]) > _MAX_FACTS:
                        data["facts"] = data["facts"][-_MAX_FACTS:]
                    _save(data)
                break


AutoMemory = _AutoMemory()
