"""
Common logging configuration for PIF Compiler project.

Provides a centralized logging setup with:
- Dual outputs: separate files for errors and debug logs
- Automatic log rotation at 1MB
- Detailed formatting: timestamp - filename - function - message
"""

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

# Single logger instance for the entire project
_logger: Optional[logging.Logger] = None


def get_logger(
    log_dir: Optional[str] = None,
    max_bytes: int = 1_000_000,  # 1MB
    backup_count: int = 5,
    console_output: bool = True,
) -> logging.Logger:
    """
    Get the centralized logger instance for the PIF Compiler project.

    Returns the same logger instance across all modules to consolidate logs
    into single debug.log and error.log files.

    Args:
        log_dir: Directory for log files. Defaults to 'logs' in project root
        max_bytes: Maximum size of log file before rotation (default: 1MB)
        backup_count: Number of backup files to keep (default: 5)
        console_output: Whether to also output logs to console (default: True)

    Returns:
        Configured logging.Logger instance

    Example:
        >>> from pif_compiler.services.common_log import get_logger
        >>> logger = get_logger()
        >>> logger.info("Processing ingredient data")
        >>> logger.error("Failed to connect to database")
    """
    global _logger

    # Return existing logger if already configured
    if _logger is not None:
        return _logger

    logger = logging.getLogger("pif_compiler")
    logger.setLevel(logging.DEBUG)  # Capture all levels

    # Determine log directory
    if log_dir is None:
        # Default to 'logs' folder in project root
        project_root = Path(__file__).parent.parent.parent.parent
        log_dir = project_root / "logs"
    else:
        log_dir = Path(log_dir)

    # Create log directory if it doesn't exist
    log_dir.mkdir(parents=True, exist_ok=True)

    # Define log format: timestamp - filename - function - level - message
    log_format = logging.Formatter(
        fmt="%(asctime)s - %(filename)s - %(funcName)s - %(levelname)s - %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S",
    )

    # --- DEBUG LOG HANDLER ---
    # Captures DEBUG and INFO level messages
    debug_handler = RotatingFileHandler(
        filename=log_dir / "debug.log",
        maxBytes=max_bytes,
        backupCount=backup_count,
        encoding="utf-8",
    )
    debug_handler.setLevel(logging.DEBUG)
    debug_handler.setFormatter(log_format)
    logger.addHandler(debug_handler)

    # --- ERROR LOG HANDLER ---
    # Captures WARNING, ERROR, and CRITICAL level messages
    error_handler = RotatingFileHandler(
        filename=log_dir / "error.log",
        maxBytes=max_bytes,
        backupCount=backup_count,
        encoding="utf-8",
    )
    error_handler.setLevel(logging.WARNING)
    error_handler.setFormatter(log_format)
    logger.addHandler(error_handler)

    # --- CONSOLE HANDLER (Optional) ---
    if console_output:
        console_handler = logging.StreamHandler()
        console_handler.setLevel(logging.DEBUG)  # Only INFO and above to console
        console_handler.setFormatter(log_format)
        logger.addHandler(console_handler)

    # Store the logger instance
    _logger = logger

    return logger
