"""
Centralized logging configuration using Rich.

This module provides project-agnostic logging setup that can be reused across projects.
All configuration is loaded from config.yaml, making it easy to customize per-project.

Usage:
    from utils.logger import get_logger, setup_logging

    # Setup logging once at application startup
    setup_logging(settings)

    # Get logger in any module
    logger = get_logger(__name__)
    logger.info("Hello world")
"""

import logging
from typing import List, Optional

from rich.console import Console
from rich.logging import RichHandler
from rich.traceback import install as install_rich_traceback

# Global console instance for consistent formatting
_console: Optional[Console] = None


def get_console() -> Console:
    """
    Get the global Rich console instance.

    Returns:
        Console: Shared Rich console instance
    """
    global _console
    if _console is None:
        _console = Console()
    return _console


def setup_logging(
    settings,
    log_level: Optional[str] = None,
    log_format: Optional[str] = None,
    show_time: bool = True,
    show_level: bool = True,
    show_path: bool = True,
    rich_tracebacks: bool = True,
    tracebacks_show_locals: bool = False,
    suppress_loggers: Optional[List[str]] = None,
) -> None:
    """
    Setup centralized logging with Rich formatting.

    This function should be called once at application startup.
    Configuration is loaded from settings (config.yaml + .env).

    Args:
        settings: Application settings instance (from config.py)
        log_level: Override log level (default: from settings.log_level)
        log_format: Log message format (default: "%(message)s")
        show_time: Show timestamp in logs
        show_level: Show log level in logs
        show_path: Show file path in logs
        rich_tracebacks: Enable Rich formatted tracebacks
        tracebacks_show_locals: Show local variables in tracebacks
        suppress_loggers: List of logger names to suppress (set to WARNING)

    Example:
        from config import settings
        from utils.logger import setup_logging

        # At application startup
        setup_logging(settings)

        # Or with custom options
        setup_logging(
            settings,
            log_level="DEBUG",
            show_path=False,
            suppress_loggers=["httpx", "httpcore"]
        )
    """
    # Get configuration from settings
    level = log_level or getattr(settings, "log_level", "INFO")

    # Get logging configuration from settings if available
    logging_config = getattr(settings, "logging", {})
    if isinstance(logging_config, dict):
        show_time = logging_config.get("show_time", show_time)
        show_level = logging_config.get("show_level", show_level)
        show_path = logging_config.get("show_path", show_path)
        rich_tracebacks = logging_config.get("rich_tracebacks", rich_tracebacks)
        tracebacks_show_locals = logging_config.get(
            "tracebacks_show_locals", tracebacks_show_locals
        )
        suppress_loggers = logging_config.get(
            "suppress_loggers", suppress_loggers or []
        )

    # Install rich tracebacks globally if enabled
    if rich_tracebacks:
        install_rich_traceback(
            console=get_console(),
            show_locals=tracebacks_show_locals,
            width=None,
            extra_lines=3,
            word_wrap=False,
            indent_guides=True,
        )

    # Create Rich handler
    handler = RichHandler(
        console=get_console(),
        rich_tracebacks=rich_tracebacks,
        tracebacks_show_locals=tracebacks_show_locals,
        markup=True,
        show_time=show_time,
        show_level=show_level,
        show_path=show_path,
    )

    # Set formatter
    formatter = logging.Formatter(log_format or "%(message)s", datefmt="[%X]")
    handler.setFormatter(formatter)

    # Configure root logger
    root_logger = logging.getLogger()
    root_logger.setLevel(getattr(logging, level.upper(), logging.INFO))

    # Remove existing handlers
    root_logger.handlers.clear()

    # Add Rich handler
    root_logger.addHandler(handler)

    # Suppress noisy third-party loggers
    default_suppress = ["httpx", "httpcore", "gradio", "urllib3", "asyncio"]
    all_suppress = list(set(default_suppress + (suppress_loggers or [])))

    for logger_name in all_suppress:
        logging.getLogger(logger_name).setLevel(logging.WARNING)

    # Log setup completion
    setup_logger = logging.getLogger("utils.logger")
    setup_logger.debug(
        f"[dim]Logging initialized: level={level}, show_time={show_time}, show_path={show_path}[/dim]"
    )


def get_logger(name: str) -> logging.Logger:
    """
    Get a logger instance for the given name.

    Args:
        name: Logger name (typically __name__ of the module)

    Returns:
        logging.Logger: Configured logger instance

    Example:
        logger = get_logger(__name__)
        logger.info("Processing started")
        logger.warning("Rate limit approaching")
        logger.error("Failed to load model", exc_info=True)
    """
    return logging.getLogger(name)


def log_info(message: str, logger_name: Optional[str] = None) -> None:
    """
    Log an info message with cyan color.

    Args:
        message: The message to log
        logger_name: Optional logger name (default: "app")
    """
    logger = get_logger(logger_name or "app")
    logger.info(f"[cyan]{message}[/cyan]")


def log_warning(message: str, logger_name: Optional[str] = None) -> None:
    """
    Log a warning message with yellow color.

    Args:
        message: The warning message to log
        logger_name: Optional logger name (default: "app")
    """
    logger = get_logger(logger_name or "app")
    logger.warning(f"[yellow]{message}[/yellow]")


def log_error(
    message: str, logger_name: Optional[str] = None, exc_info: bool = False
) -> None:
    """
    Log an error message with red color.

    Args:
        message: The error message to log
        logger_name: Optional logger name (default: "app")
        exc_info: If True, include exception traceback
    """
    logger = get_logger(logger_name or "app")
    logger.error(f"[red]{message}[/red]", exc_info=exc_info)


def log_debug(message: str, logger_name: Optional[str] = None) -> None:
    """
    Log a debug message with dim color.

    Args:
        message: The debug message to log
        logger_name: Optional logger name (default: "app")
    """
    logger = get_logger(logger_name or "app")
    logger.debug(f"[dim]{message}[/dim]")


def log_success(message: str, logger_name: Optional[str] = None) -> None:
    """
    Log a success message with green color.

    Args:
        message: The success message to log
        logger_name: Optional logger name (default: "app")
    """
    logger = get_logger(logger_name or "app")
    logger.info(f"[green]✓[/green] {message}")
