import json, os, math, time
from collections import defaultdict

class AdaptiveMemory:
    def __init__(self, memory_file="tcia_adaptive.json", decay_rate=0.0001):
        self.memory_file = memory_file
        self.decay_rate = decay_rate
        self.data = defaultdict(lambda: {"weight": 1.0, "response": None, "last": time.time()})
        self._load()

    def _load(self):
        if os.path.exists(self.memory_file):
            with open(self.memory_file, "r", encoding="utf-8") as f:
                stored = json.load(f)
                for k, v in stored.items():
                    self.data[k] = v

    def _save(self):
        with open(self.memory_file, "w", encoding="utf-8") as f:
            json.dump(self.data, f, ensure_ascii=False, indent=2)

    def normalize(self, text):
        return "".join(ch.lower() for ch in text if ch.isalnum() or ch.isspace()).strip()

    def update(self, msg, resp):
        key = self.normalize(msg)
        entry = self.data[key]
        now = time.time()
        age = now - entry["last"]
        entry["weight"] *= math.exp(-self.decay_rate * age)
        entry["weight"] += 1.0
        entry["response"] = resp
        entry["last"] = now
        self.data[key] = entry
        self._save()

    def recall(self, msg):
        key = self.normalize(msg)
        if key not in self.data:
            return None
        entry = self.data[key]
        age = time.time() - entry["last"]
        weight = entry["weight"] * math.exp(-self.decay_rate * age)
        entry["weight"] = weight
        self.data[key] = entry
        return entry["response"] if weight > 0.5 else None

    def stats(self):
        total = len(self.data)
        mean_weight = sum(e["weight"] for e in self.data.values()) / max(total,1)
        return {"entradas": total, "peso_médio": round(mean_weight,3)}