"""
utils/logger.py
───────────────
Xlancer Bot — Professional Logging System

Features:
  - Color-coded terminal output (DEBUG=cyan, INFO=green, WARNING=yellow, ERROR=red, CRITICAL=magenta)
  - Rotating file handler: logs/bot.log   (all levels, 5 MB × 7 files)
  - Rotating file handler: logs/errors.log (ERROR+ only, 2 MB × 5 files)
  - Clean, readable format with module name and line number

Usage (in any handler/module):
    from utils.logger import get_logger
    logger = get_logger(__name__)
    
    logger.debug("detailed debug info")
    logger.info("normal operation info")
    logger.warning("something unexpected")
    logger.error("something failed", exc_info=True)
    logger.critical("bot is dying")
"""

import logging
import logging.handlers
import os
import sys

# ── Constants ──────────────────────────────────────────────────────────────
LOGS_DIR       = os.path.join(os.path.dirname(os.path.dirname(__file__)), "logs")
BOT_LOG_FILE   = os.path.join(LOGS_DIR, "bot.log")
ERROR_LOG_FILE = os.path.join(LOGS_DIR, "errors.log")

MAX_BYTES      = 5 * 1024 * 1024   # 5 MB per file
BACKUP_COUNT   = 7                  # keep last 7 bot.log files
ERROR_MAX      = 2 * 1024 * 1024   # 2 MB per error file
ERROR_BACKUP   = 5                  # keep last 5 error files

LOG_FORMAT     = "[%(asctime)s] [%(levelname)-8s] %(name)-30s %(message)s"
DATE_FORMAT    = "%Y-%m-%d %H:%M:%S"

# ── ANSI color codes ────────────────────────────────────────────────────────
class _Color:
    RESET   = "\033[0m"
    BOLD    = "\033[1m"
    DIM     = "\033[2m"
    # levels
    DEBUG   = "\033[96m"   # cyan
    INFO    = "\033[92m"   # green
    WARNING = "\033[93m"   # yellow
    ERROR   = "\033[91m"   # red
    CRITICAL= "\033[95m"   # magenta

_LEVEL_COLORS = {
    logging.DEBUG:    _Color.DEBUG,
    logging.INFO:     _Color.INFO,
    logging.WARNING:  _Color.WARNING,
    logging.ERROR:    _Color.ERROR,
    logging.CRITICAL: _Color.CRITICAL,
}

# ── Formatters ──────────────────────────────────────────────────────────────
class _ColorFormatter(logging.Formatter):
    """Color-coded formatter for terminal output."""

    def format(self, record: logging.LogRecord) -> str:
        color  = _LEVEL_COLORS.get(record.levelno, _Color.RESET)
        reset  = _Color.RESET
        bold   = _Color.BOLD
        dim    = _Color.DIM

        # Timestamp (dim gray)
        ts = self.formatTime(record, self.datefmt)

        # Level (colored + fixed width)
        level_str = f"{color}{bold}[{record.levelname:<8}]{reset}"

        # Module name (dim, truncated to 28 chars)
        name = record.name
        if len(name) > 28:
            parts = name.split(".")
            name = ".".join(p[0] for p in parts[:-1]) + "." + parts[-1]
            name = name[-28:]
        name_str = f"{dim}{name:<28}{reset}"

        # Message (colored)
        msg = record.getMessage()
        
        # Exception info
        exc_text = ""
        if record.exc_info:
            exc_text = "\n" + self.formatException(record.exc_info)

        return f"{dim}[{ts}]{reset} {level_str} {name_str}  {color}{msg}{reset}{exc_text}"


class _PlainFormatter(logging.Formatter):
    """Plain formatter for log files (no ANSI codes)."""
    pass


# ── Setup function ──────────────────────────────────────────────────────────
_initialized = False

def setup_logging(level: int = logging.DEBUG) -> None:
    """
    Configure the root logger with:
      - A color-coded StreamHandler (terminal)
      - A rotating FileHandler for all logs → logs/bot.log
      - A rotating FileHandler for errors  → logs/errors.log
    
    Call once from bot.py before anything else.
    """
    global _initialized
    if _initialized:
        return
    _initialized = True

    # Create logs directory
    os.makedirs(LOGS_DIR, exist_ok=True)

    # Fix Windows terminal encoding
    if os.name == "nt":
        try:
            sys.stdout.reconfigure(encoding="utf-8", errors="replace")
            sys.stderr.reconfigure(encoding="utf-8", errors="replace")
            os.system("color")  # enable ANSI colors in CMD
        except Exception:
            pass

    root = logging.getLogger()
    root.setLevel(level)

    # Remove any existing handlers (e.g., from basicConfig)
    root.handlers.clear()

    # 1. Terminal — color, INFO+ only (suppress noisy libs to WARNING)
    console = logging.StreamHandler(sys.stdout)
    console.setLevel(logging.INFO)
    console.setFormatter(_ColorFormatter(fmt=LOG_FORMAT, datefmt=DATE_FORMAT))
    root.addHandler(console)

    # 2. bot.log — all levels (DEBUG+), rotating
    file_all = logging.handlers.RotatingFileHandler(
        BOT_LOG_FILE,
        maxBytes=MAX_BYTES,
        backupCount=BACKUP_COUNT,
        encoding="utf-8"
    )
    file_all.setLevel(logging.DEBUG)
    file_all.setFormatter(_PlainFormatter(fmt=LOG_FORMAT, datefmt=DATE_FORMAT))
    root.addHandler(file_all)

    # 3. errors.log — ERROR+ only, rotating
    file_err = logging.handlers.RotatingFileHandler(
        ERROR_LOG_FILE,
        maxBytes=ERROR_MAX,
        backupCount=ERROR_BACKUP,
        encoding="utf-8"
    )
    file_err.setLevel(logging.ERROR)
    file_err.setFormatter(_PlainFormatter(fmt=LOG_FORMAT, datefmt=DATE_FORMAT))
    root.addHandler(file_err)

    # Suppress noisy third-party loggers
    for noisy in ("aiogram.event", "aiosqlite", "aiohttp.access", "urllib3"):
        logging.getLogger(noisy).setLevel(logging.WARNING)

    root.info("=" * 65)
    root.info("  Xlancer Bot Logger initialized")
    root.info(f"  All logs  → {BOT_LOG_FILE}")
    root.info(f"  Errors    → {ERROR_LOG_FILE}")
    root.info("=" * 65)


def get_logger(name: str) -> logging.Logger:
    """
    Get a named logger. Use __name__ as the name.

    Example:
        from utils.logger import get_logger
        logger = get_logger(__name__)
    """
    return logging.getLogger(name)
