"""Logger module for pytola.

This module provides a colored logging system with structured output support,
file rotation, and configurable log levels for the pytola application.
"""

from __future__ import annotations

import logging
import logging.handlers
import sys
from pathlib import Path
from typing import ClassVar, Final

# Log file configuration
LOG_DIR: Final[Path] = Path.home() / ".pytola" / "logs"
LOG_FILE: Final[Path] = LOG_DIR / "pytola.log"
MAX_BYTES: Final[int] = 10 * 1024 * 1024  # 10MB
BACKUP_COUNT: Final[int] = 5


class ColoredLogger:
    """A singleton logger class that provides colored console output and file logging.

    This class ensures only one logger instance exists throughout the application
    lifecycle, providing consistent logging behavior across all modules.

    Attributes
    ----------
        _instance: The singleton logger instance
        COLORS: ANSI color codes for different log levels
    """

    _instance: logging.Logger | None = None

    COLORS: ClassVar[dict[str, str]] = {
        "DEBUG": "\033[36m",  # CYAN
        "INFO": "\033[32m",  # GREEN
        "WARNING": "\033[33m",  # YELLOW
        "ERROR": "\033[31m",  # RED
        "CRITICAL": "\033[41m",  # White on Red Background
        "RESET": "\033[0m",  # RESET COLOR
    }

    @classmethod
    def get_logger(cls, name: str = "pytola") -> logging.Logger:
        """Get or create the logger instance.

        Args:
            name: Logger name. Defaults to "pytola"

        Returns
        -------
            Configured logger instance
        """
        if cls._instance is None:
            cls._instance = cls.setup_logger(name)

        return cls._instance

    @classmethod
    def setup_logger(cls, name: str) -> logging.Logger:
        """Set up the logger with console and file handlers.

        Parameters
        ----------
        name : str
            Logger name

        Returns
        -------
        logging.Logger
            Configured logger with both console and file handlers
        """
        # Ensure log directory exists
        try:
            LOG_DIR.mkdir(parents=True, exist_ok=True)
        except OSError as e:
            # If we can't create log dir, continue without file handler
            print(f"Warning: Could not create log directory {LOG_DIR}: {e}")

        class _ColoredFormatter(logging.Formatter):
            """Custom formatter that adds ANSI colors to log messages."""

            def format(self, record: logging.LogRecord) -> str:
                """Format the log record with appropriate colors.

                Args:
                    record: Log record to format

                Returns
                -------
                    Colored formatted log message
                """
                log_color = cls.COLORS.get(record.levelname, cls.COLORS["RESET"])
                message = super().format(record)
                return f"{log_color}{message}{ColoredLogger.COLORS['RESET']}"

        # Create logger
        logger = logging.getLogger(name)
        logger.setLevel(logging.DEBUG)  # Set to DEBUG to capture all levels

        # Console handler - INFO level
        console_handler = logging.StreamHandler(sys.stdout)
        console_handler.setLevel(logging.INFO)
        console_formatter = _ColoredFormatter("%(levelname)s - %(message)s")
        console_handler.setFormatter(console_formatter)

        # File handler - DEBUG level with rotation
        file_handler = logging.handlers.RotatingFileHandler(
            LOG_FILE,
            maxBytes=MAX_BYTES,
            backupCount=BACKUP_COUNT,
            encoding="utf-8",
        )
        file_handler.setLevel(logging.DEBUG)
        file_formatter = logging.Formatter(
            "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
            datefmt="%Y-%m-%d %H:%M:%S",
        )
        file_handler.setFormatter(file_formatter)

        # Add handlers
        logger.addHandler(console_handler)
        logger.addHandler(file_handler)

        # Prevent adding handlers multiple times
        logger.propagate = False

        return logger


get_logger = ColoredLogger.get_logger

logger = ColoredLogger.get_logger()
logger.DEBUG = logging.DEBUG
logger.INFO = logging.INFO
logger.WARNING = logging.WARNING
logger.ERROR = logging.ERROR
logger.CRITICAL = logging.CRITICAL
