import logging
from logging.handlers import RotatingFileHandler
from pathlib import Path


def get_logger(name: str = "dracula") -> logging.Logger:
    """
    Get the Dracula logger.

    Args:
        name (str): Logger name. Defaults to 'dracula'.

    Returns:
        logging.Logger: Configured logger instance.
    """

    logger = logging.getLogger(name)

    if not logger.handlers:

        logger.addHandler(logging.NullHandler())

        handler = logging.StreamHandler()
        formatter = logging.Formatter(
            fmt="%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s",
            datefmt="%Y-%m-%d %H:%M:%S",
        )

        handler.setFormatter(formatter)
        logger.addHandler(handler)
        logger.setLevel(logging.WARNING)

    return logger


def enable_logging():
    """
    Enable Dracula logging.

    Args:
        level (str): Logging level. Options are:
                    'DEBUG'    - Everything, very detailed
                    'INFO'     - General information
                    'WARNING'  - Only warnings
                    'ERROR'    - Only errors
                    'CRITICAL' - Only critical errors
    """
    levels = {
        "DEBUG": logging.DEBUG,
        "INFO": logging.INFO,
        "WARNING": logging.WARNING,
        "ERROR": logging.ERROR,
        "CRITICAL": logging.CRITICAL,
    }
    level = level.upper()
    if level not in levels:
        raise ValueError(
            f"Invalid log level '{level}'. Choose from: {', '.join(levels.keys())}"
        )

    logging.getLogger("dracula").setLevel(levels[level])


def disable_logging():
    """Disable Dracula logging."""
    logging.getLogger("dracula").setLevel(logging.CRITICAL)


def enable_file_logging(
    filepath: str, max_bytes: int = 5 * 1024 * 1024, backup_count: int = 5
):
    """
    Enable logging to a file with automatic log rotation.

    When the log file reaches max_bytes, it is automatically renamed
    and a new log file is created. Up to backup_count old log files
    are kept before the oldest one is deleted.

    Args:
        filepath (str): Path to the log file (e.g. 'dracula.log').
        max_bytes (int): Maximum file size in bytes before rotation. Defaults to 5MB.
        backup_count (int): Number of backup files to keep. Defaults to 5.

    Example:
        With filepath='dracula.log' and backup_count=5, the files will be:
        dracula.log, dracula.log.1, dracula.log.2, dracula.log.3, dracula.log.4, dracula.log.5
    """

    logger = logger.get_logger("dracula")

    # Check if file handler already exists to avoid duplicates
    for handler in logger.handlers:
        if isinstance(handler, RotatingFileHandler):
            return

    path = Path(filepath)
    path.parent.mkdir(parents=True, exist_ok=True)

    formatter = logging.Formatter(
        fmt="%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S",
    )
    file_handler = RotatingFileHandler(
        path, maxBytes=max_bytes, backupCount=backup_count, encoding="utf-8"
    )
    file_handler.setFormatter(formatter)
    logger.addHandler(file_handler)


def disable_file_logging():
    """Disable logging to a file."""
    logger = logging.getLogger("dracula")
    logger.handlers = [
        h for h in logger.handlers if not isinstance(h, RotatingFileHandler)
    ]
