"""
Configuration and logging setup for ScalarGrad.
"""

import logging
import random
from dataclasses import dataclass, field
from enum import Enum
from typing import Optional

from rich.logging import RichHandler


class LogLevel(Enum):
    """Enumeration for logging levels."""
    DEBUG = logging.DEBUG
    INFO = logging.INFO
    WARNING = logging.WARNING
    ERROR = logging.ERROR


@dataclass
class Config:
    """
    Global configuration for ScalarGrad.

    The ``theme`` field controls the active colour palette used
    throughout the library.  Any name registered in
    :data:`scalargrad.theme.THEMES` is accepted.  Built-in options::

        "default"   — blue / green sci-fi  (dark terminals)
        "dark"      — purple / cyan electro
        "cyberpunk" — neon magenta / yellow
        "light"     — muted tones for bright-background terminals
        "minimal"   — bold / italic only, no colour

    The ``training_display`` field controls how training progress is shown::

        "progress"  — single updating progress bar (default, works everywhere)
        "table"     — live-updating table with epoch / loss / accuracy / time

    Example::

        from scalargrad import config
        config.theme = "cyberpunk"         # switch colour palette
        config.training_display = "table"  # switch to table view
    """
    log_level: LogLevel = LogLevel.INFO
    seed: Optional[int] = None
    gradient_clip: Optional[float] = None
    numerical_stability_epsilon: float = 1e-8
    theme: str = field(default="default")
    training_display: str = field(default="progress")

    def __post_init__(self):
        """Initialize logging (via RichHandler) and random seed."""
        # Remove any previously configured handlers to avoid duplicates
        root_logger = logging.getLogger()
        root_logger.handlers.clear()

        logging.basicConfig(
            level=self.log_level.value,
            format="%(message)s",
            datefmt="[%X]",
            handlers=[RichHandler(
                rich_tracebacks=True,
                show_path=False,
                markup=True,
            )],
        )

        if self.seed is not None:
            random.seed(self.seed)

        # Apply theme — import lazily to avoid circular dependency
        try:
            from . import theme as _theme_mod
            _theme_mod.set_theme(self.theme)
        except Exception:
            pass

    def __setattr__(self, name: str, value: object) -> None:
        """React to live theme changes made after initialisation."""
        super().__setattr__(name, value)
        if name == "theme":
            try:
                from . import theme as _theme_mod
                _theme_mod.set_theme(str(value))
            except Exception:
                pass


# Global configuration instance
config = Config()
logger = logging.getLogger(__name__)
