"""SAGE Logging Configuration.

Provides structured logging setup with JSON formatting for production
and human-readable formatting for development.
"""

import logging
import logging.handlers
import sys
from datetime import UTC, datetime
from pathlib import Path
from typing import Any

try:
    from pythonjsonlogger import jsonlogger
except ImportError:
    jsonlogger = None  # type: ignore[assignment]


class SAGELogFormatter(logging.Formatter):
    """Custom formatter for SAGE with colored output for development."""

    COLORS = {
        "DEBUG": "\033[36m",     # Cyan
        "INFO": "\033[32m",      # Green
        "WARNING": "\033[33m",   # Yellow
        "ERROR": "\033[31m",     # Red
        "CRITICAL": "\033[35m",  # Magenta
    }
    RESET = "\033[0m"

    def __init__(self, use_colors: bool = True):
        """Initialize formatter.

        Args:
            use_colors: Whether to use ANSI colors in output.
        """
        super().__init__()
        self.use_colors = use_colors and sys.stderr.isatty()

    def format(self, record: logging.LogRecord) -> str:
        """Format log record with optional colors."""
        timestamp = datetime.now(UTC).strftime("%Y-%m-%d %H:%M:%S")
        level = record.levelname
        name = record.name
        message = record.getMessage()

        # Add exception info if present
        if record.exc_info:
            message += "\n" + self.formatException(record.exc_info)

        if self.use_colors:
            color = self.COLORS.get(level, "")
            return f"{timestamp} {color}{level:8}{self.RESET} [{name}] {message}"
        return f"{timestamp} {level:8} [{name}] {message}"


class SAGEJSONFormatter(logging.Formatter):
    """JSON formatter for structured logging in production."""

    def __init__(self, **kwargs: Any):
        """Initialize JSON formatter."""
        super().__init__()
        self.default_fields = kwargs

    def format(self, record: logging.LogRecord) -> str:
        """Format log record as JSON."""
        import json

        log_entry = {
            "timestamp": datetime.now(UTC).isoformat(),
            "level": record.levelname,
            "logger": record.name,
            "message": record.getMessage(),
            "module": record.module,
            "function": record.funcName,
            "line": record.lineno,
        }

        # Add default fields
        log_entry.update(self.default_fields)

        # Add extra fields from record
        for key, value in record.__dict__.items():
            if key not in {
                "name", "msg", "args", "created", "filename", "funcName",
                "levelname", "levelno", "lineno", "module", "msecs",
                "pathname", "process", "processName", "relativeCreated",
                "stack_info", "exc_info", "exc_text", "thread", "threadName",
                "message", "taskName",
            }:
                log_entry[key] = value

        # Add exception info if present
        if record.exc_info:
            log_entry["exception"] = self.formatException(record.exc_info)

        return json.dumps(log_entry, default=str)


def setup_logging(
    level: str = "INFO",
    json_format: bool = False,
    log_file: str | Path | None = None,
    service_name: str = "sage",
) -> logging.Logger:
    """Configure application logging.

    Args:
        level: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL).
        json_format: Use JSON formatting (recommended for production).
        log_file: Optional file path for logging output.
        service_name: Service name to include in logs.

    Returns:
        Logger: Configured root logger for SAGE.
    """
    # Get numeric level
    numeric_level = getattr(logging, level.upper(), logging.INFO)

    # Get or create SAGE logger
    logger = logging.getLogger("sage")
    logger.setLevel(numeric_level)
    logger.handlers.clear()

    # Choose formatter based on environment
    if json_format:
        if jsonlogger is not None:
            formatter: logging.Formatter = jsonlogger.JsonFormatter(
                "%(timestamp)s %(level)s %(name)s %(message)s",
                timestamp=True,
            )
        else:
            formatter = SAGEJSONFormatter(service=service_name)
    else:
        formatter = SAGELogFormatter(use_colors=True)

    # Console handler
    console_handler = logging.StreamHandler(sys.stderr)
    console_handler.setLevel(numeric_level)
    console_handler.setFormatter(formatter)
    logger.addHandler(console_handler)

    # File handler (optional)
    if log_file:
        log_path = Path(log_file)
        log_path.parent.mkdir(parents=True, exist_ok=True)

        file_handler = logging.handlers.RotatingFileHandler(
            log_path,
            maxBytes=10 * 1024 * 1024,  # 10MB
            backupCount=5,
            encoding="utf-8",
        )
        file_handler.setLevel(numeric_level)
        # Always use JSON for file logs
        file_handler.setFormatter(SAGEJSONFormatter(service=service_name))
        logger.addHandler(file_handler)

    # Prevent propagation to root logger
    logger.propagate = False

    # Configure third-party loggers to be less verbose
    logging.getLogger("httpx").setLevel(logging.WARNING)
    logging.getLogger("httpcore").setLevel(logging.WARNING)
    logging.getLogger("openai").setLevel(logging.WARNING)
    logging.getLogger("anthropic").setLevel(logging.WARNING)
    logging.getLogger("qdrant_client").setLevel(logging.WARNING)

    logger.info(
        "Logging configured",
        extra={
            "log_level": level,
            "json_format": json_format,
            "log_file": str(log_file) if log_file else None,
        },
    )

    return logger


def get_logger(name: str) -> logging.Logger:
    """Get a logger with the SAGE namespace.

    Args:
        name: Logger name (will be prefixed with 'sage.').

    Returns:
        Logger: Configured logger instance.
    """
    if name.startswith("sage."):
        return logging.getLogger(name)
    return logging.getLogger(f"sage.{name}")
