"""
candy.monitor — Dashboard terminal v16
========================================

Dashboard ASCII basé sur les logs locaux.
Affiche top personnalités, scores prompts, temps moyen, tendances.

Usage :
    from candy import Monitor
    Monitor.show()           # dashboard complet dans le terminal
    Monitor.top()            # top 5 personnalités
    Monitor.report()         # dict avec toutes les stats
    Monitor.export("stats.json")
"""

import json
from pathlib import Path
from typing import Optional


class _Monitor:

    DEFAULT_LOG = Path.home() / ".candy" / "logs"

    def _load_logs(self, log_name: str = "*") -> list:
        """Charge tous les logs disponibles."""
        entries = []
        log_dir = self.DEFAULT_LOG
        if not log_dir.exists():
            return []
        pattern = f"{log_name}.json" if log_name != "*" else "*.json"
        for f in log_dir.glob(pattern):
            try:
                data = json.loads(f.read_text(encoding="utf-8"))
                entries.extend(data.get("entries", []))
            except Exception:
                pass
        return entries

    def report(self, log_name: str = "*") -> dict:
        """Retourne un dict complet des statistiques."""
        entries = self._load_logs(log_name)
        if not entries:
            return {"total": 0, "message": "Aucun log trouvé. Lance des requêtes d'abord."}

        personalities = {}
        scores        = []
        times         = []
        errors        = 0
        daily         = {}

        for e in entries:
            p = e.get("personality", "unknown")
            personalities[p] = personalities.get(p, 0) + 1

            s = e.get("prompt_score")
            if s is not None:
                scores.append(s)

            t = e.get("time_ms", 0)
            if t:
                times.append(t)

            if e.get("error"):
                errors += 1

            date = e.get("timestamp", "")[:10]
            if date:
                daily[date] = daily.get(date, 0) + 1

        top = sorted(personalities.items(), key=lambda x: x[1], reverse=True)[:5]

        return {
            "total":            len(entries),
            "errors":           errors,
            "error_rate":       round(errors / len(entries) * 100, 1) if entries else 0,
            "top_personalities":dict(top),
            "avg_prompt_score": round(sum(scores) / len(scores), 1) if scores else 0,
            "min_score":        min(scores) if scores else 0,
            "max_score":        max(scores) if scores else 0,
            "avg_time_ms":      round(sum(times) / len(times), 1) if times else 0,
            "daily_usage":      dict(sorted(daily.items())[-7:]),
            "total_personalities_used": len(personalities),
        }

    def show(self, log_name: str = "*"):
        """Affiche le dashboard complet dans le terminal."""
        r     = self.report(log_name)
        gray  = "\033[90m"
        cyan  = "\033[96m"
        green = "\033[92m"
        yellow= "\033[93m"
        red   = "\033[91m"
        bold  = "\033[1m"
        reset = "\033[0m"

        if r.get("total", 0) == 0:
            print(f"\n  {yellow}⚠ Aucun log trouvé.{reset}")
            print(f"  {gray}Lance des requêtes puis réessaie.{reset}\n")
            return

        print(f"\n  {bold}{cyan}🍬 Candy Monitor v16{reset}")
        print(f"  {gray}{'─' * 44}{reset}")

        # Total
        print(f"\n  {gray}📊 Total requêtes   {reset}{bold}{r['total']}{reset}  "
              f"{gray}Erreurs {reset}{red}{r['errors']}{reset} {gray}({r['error_rate']}%){reset}")

        # Scores
        avg_s = r["avg_prompt_score"]
        score_col = green if avg_s >= 70 else yellow if avg_s >= 50 else red
        print(f"  {gray}🎯 Score moyen      {reset}{score_col}{avg_s}/100{reset}  "
              f"{gray}Min {r['min_score']} · Max {r['max_score']}{reset}")

        # Temps
        print(f"  {gray}⚡ Temps moyen      {reset}{r['avg_time_ms']} ms")

        # Top personnalités
        print(f"\n  {gray}🏆 Top personnalités{reset}")
        top = list(r["top_personalities"].items())
        max_count = top[0][1] if top else 1
        for name, count in top:
            bar_len = int(20 * count / max_count)
            bar     = "█" * bar_len + "░" * (20 - bar_len)
            pct     = round(count / r["total"] * 100)
            print(f"  {cyan}{name:<16}{reset} {gray}{bar}{reset} {count} {gray}({pct}%){reset}")

        # Activité 7 jours
        print(f"\n  {gray}📅 Activité (7 derniers jours){reset}")
        daily = r["daily_usage"]
        if daily:
            max_day = max(daily.values()) if daily.values() else 1
            for date, count in daily.items():
                bar_len = int(20 * count / max_day)
                bar     = "█" * bar_len
                print(f"  {gray}{date}{reset}  {green}{bar:<20}{reset} {count}")

        print(f"\n  {gray}{'─' * 44}{reset}")
        print(f"  {gray}Logs dans ~/.candy/logs/{reset}\n")

    def top(self, n: int = 5, log_name: str = "*") -> list:
        """Retourne les N personnalités les plus utilisées."""
        r = self.report(log_name)
        return list(r.get("top_personalities", {}).items())[:n]

    def export(self, path: str, log_name: str = "*"):
        """Exporte les stats vers un fichier JSON."""
        r = self.report(log_name)
        Path(path).write_text(json.dumps(r, ensure_ascii=False, indent=2), encoding="utf-8")
        print(f"✅ Stats exportées → {path}")

    def clear_logs(self, confirm: bool = False):
        """Supprime tous les logs. confirm=True requis."""
        if not confirm:
            print("⚠ Passe confirm=True pour supprimer les logs.")
            return
        log_dir = self.DEFAULT_LOG
        if log_dir.exists():
            for f in log_dir.glob("*.json"):
                f.unlink()
            print("✅ Logs supprimés.")


Monitor = _Monitor()
