"""
candy.config — Système de profils Cedric8-Thinking v5
=================================================

IMPORT :
    from candy import cfg

CRÉER UN PROFIL :
    cfg.A.lang          = "FR"
    cfg.A.max_tokens    = 1500
    cfg.A.style         = "detailed"
    cfg.A.tone          = "encouraging"
    cfg.A.expertise     = "beginner"
    cfg.A.output_format = "markdown"

UTILISER UN PROFIL :
    from candy import Coding
    Coding.use("A").ask("Explique les décorateurs")

PROFIL DEFAULT (sans .use()) :
    cfg.default.lang  = "FR"
    cfg.default.style = "concise"
    Coding.ask("Hello")

PRESETS RAPIDES :
    cfg.A = cfg.preset("coder")
    cfg.B = cfg.preset("french_beginner")

PARAMÈTRES :
┌──────────────────┬───────────────┬──────────────────────────────────────────┐
│ Paramètre        │ Défaut        │ Valeurs possibles                        │
├──────────────────┼───────────────┼──────────────────────────────────────────┤
│ lang             │ "EN"          │ FR EN ES DE IT PT ZH JA AR RU NL PL SV   │
│                  │               │ TR KO HI VI ID CS RO                     │
│ max_tokens       │ 1024          │ 100=court 600=moyen 1024=std 4096=max    │
│ temperature      │ 0.7           │ 0.0=factuel → 1.5=très créatif           │
│ style            │ "default"     │ default concise detailed bullet academic  │
│                  │               │ casual technical eli5                    │
│ tone             │ "neutral"     │ neutral encouraging strict humorous       │
│                  │               │ empathetic socratic                      │
│ output_format    │ "text"        │ text markdown json html                  │
│ expertise        │ "intermediate"│ beginner intermediate expert             │
│ include_examples │ True          │ True / False                             │
│ safe_mode        │ True          │ True / False                             │
│ timeout          │ 120           │ secondes                                 │
│ cache_url        │ True          │ True / False                             │
│ retry            │ 1             │ nb de tentatives en cas d'échec          │
│ verbose          │ False         │ True = affiche les infos de requête      │
└──────────────────┴───────────────┴──────────────────────────────────────────┘
"""

_DEFAULTS = {
    "lang":             "EN",
    "max_tokens":       800,
    "temperature":      0.7,
    "style":            "default",
    "tone":             "neutral",
    "output_format":    "text",
    "expertise":        "intermediate",
    "include_examples": True,
    "safe_mode":        True,
    "timeout":          120,
    "cache_url":        True,
    "retry":            1,
    "verbose":          False,
}

_PRESETS = {
    "french_beginner": {
        "lang": "FR", "style": "detailed", "tone": "encouraging",
        "expertise": "beginner", "max_tokens": 1500, "include_examples": True,
    },
    "french_expert": {
        "lang": "FR", "style": "concise", "tone": "strict",
        "expertise": "expert", "max_tokens": 600,
    },
    "english_beginner": {
        "lang": "EN", "style": "detailed", "tone": "encouraging",
        "expertise": "beginner", "max_tokens": 1500, "include_examples": True,
    },
    "english_expert": {
        "lang": "EN", "style": "technical", "tone": "strict",
        "expertise": "expert", "max_tokens": 800,
    },
    "quick": {
        "style": "concise", "max_tokens": 120, "tone": "neutral",
    },
    "academic": {
        "style": "academic", "output_format": "markdown",
        "max_tokens": 2000, "tone": "neutral", "expertise": "expert",
    },
    "creative": {
        "style": "casual", "temperature": 1.1, "tone": "humorous",
        "max_tokens": 1500, "include_examples": True,
    },
    "teacher": {
        "style": "detailed", "tone": "encouraging", "expertise": "beginner",
        "output_format": "markdown", "max_tokens": 2000, "include_examples": True,
    },
    "coder": {
        "style": "technical", "output_format": "markdown",
        "expertise": "expert", "max_tokens": 3000, "tone": "strict",
    },
    "journalist": {
        "style": "detailed", "output_format": "markdown",
        "tone": "neutral", "max_tokens": 2000,
    },
    "storyteller": {
        "style": "casual", "temperature": 1.2, "tone": "humorous",
        "max_tokens": 4096, "include_examples": False,
    },
    "analyst": {
        "style": "bullet", "output_format": "markdown",
        "tone": "strict", "expertise": "expert", "max_tokens": 2000,
    },
    "coach": {
        "style": "detailed", "tone": "encouraging",
        "expertise": "intermediate", "max_tokens": 1500,
    },
    "debug": {
        "style": "technical", "output_format": "markdown",
        "expertise": "expert", "max_tokens": 3000, "tone": "strict",
        "include_examples": True,
    },
}


class Profile:
    """Profil de configuration Cedric8-Thinking."""

    def __init__(self, name: str, overrides: dict = None):
        object.__setattr__(self, "_name", name)
        defaults = dict(_DEFAULTS)
        if overrides:
            defaults.update(overrides)
        for k, v in defaults.items():
            object.__setattr__(self, k, v)

    def copy_from(self, other: "Profile"):
        for k in _DEFAULTS:
            object.__setattr__(self, k, getattr(other, k))

    def reset(self):
        """Remet tous les paramètres aux valeurs par défaut."""
        for k, v in _DEFAULTS.items():
            object.__setattr__(self, k, v)

    def to_dict(self) -> dict:
        return {k: getattr(self, k) for k in _DEFAULTS}

    def summary(self) -> str:
        changed = {k: getattr(self, k) for k in _DEFAULTS if getattr(self, k) != _DEFAULTS[k]}
        if not changed:
            return f'Profile("{object.__getattribute__(self, "_name")}") — défauts'
        parts = ", ".join(f"{k}={repr(v)}" for k, v in changed.items())
        return f'Profile("{object.__getattribute__(self, "_name")}") — {parts}'

    def __repr__(self):
        name = object.__getattribute__(self, "_name")
        lines = [f'\033[96mProfil \033[97m"{name}"\033[0m']
        for k in _DEFAULTS:
            v = getattr(self, k)
            if v != _DEFAULTS[k]:
                lines.append(f"  \033[93m{k:20s}\033[0m = \033[92m{repr(v)}\033[90m  ←\033[0m")
            else:
                lines.append(f"  \033[90m{k:20s} = {repr(v)}\033[0m")
        return "\n".join(lines)


class _Config:
    """Registre global des profils candy."""

    def __init__(self):
        object.__setattr__(self, "_profiles", {})
        self._get_or_create("default")

    def _get_or_create(self, name: str) -> Profile:
        profiles = object.__getattribute__(self, "_profiles")
        if name not in profiles:
            profiles[name] = Profile(name)
        return profiles[name]

    def __getattr__(self, name: str) -> Profile:
        if name.startswith("_"):
            raise AttributeError(name)
        return self._get_or_create(name)

    def __setattr__(self, name: str, value):
        if name.startswith("_"):
            object.__setattr__(self, name, value)
            return
        if isinstance(value, Profile):
            p = self._get_or_create(name)
            p.copy_from(value)
            return
        raise AttributeError(
            f"Utilise cfg.{name}.param = valeur\n"
            f"Ou un preset : cfg.{name} = cfg.preset('coder')"
        )

    def preset(self, name: str) -> Profile:
        """
        Retourne un profil préconfiguré.

        Presets : french_beginner  french_expert  english_beginner  english_expert
                  quick  academic  creative  teacher  coder  journalist
                  storyteller  analyst  coach  debug
        """
        if name not in _PRESETS:
            available = ", ".join(_PRESETS.keys())
            raise ValueError(f"Preset inconnu : '{name}'. Disponibles : {available}")
        return Profile(f"preset:{name}", _PRESETS[name])

    def list(self) -> list:
        return list(object.__getattribute__(self, "_profiles").keys())

    def list_presets(self) -> list:
        return list(_PRESETS.keys())

    def get(self, name: str) -> Profile:
        return self._get_or_create(name)

    def __repr__(self):
        profiles = object.__getattribute__(self, "_profiles")
        lines = ["\033[95m🍬 candy.config\033[0m — profils :"]
        for name, p in profiles.items():
            lines.append(f"  \033[96m[{name}]\033[0m {p.summary()}")
        return "\n".join(lines)


config = _Config()


def get_profile(name: str) -> Profile:
    return config.get(name)


def list_profiles() -> list:
    return config.list()
