import logging
from logging.handlers import TimedRotatingFileHandler
import os
from pathlib import Path
from dotenv import load_dotenv

load_dotenv()

# Custom log level (optional). Keep for backward compatibility.
CUSTOM_ERROR_LEVEL = 35
logging.addLevelName(CUSTOM_ERROR_LEVEL, "CUSTOM_ERROR")


def custom_error(self, message, *args, **kwargs):
    """Helper to log at the custom error level."""
    if self.isEnabledFor(CUSTOM_ERROR_LEVEL):
        self._log(CUSTOM_ERROR_LEVEL, message, args, **kwargs)

# Attach helper to the Logger class so callers can do: logging.getLogger().custom_error(...)
logging.Logger.custom_error = custom_error


def _ensure_dir_for_file(path: str):
    """Ensure the parent directory for `path` exists."""
    Path(path).resolve().parent.mkdir(parents=True, exist_ok=True)


def _create_timed_handler(path: str, level=None, when='midnight', interval=1, backupCount=7, fmt=None):
    """
    Create and configure a TimedRotatingFileHandler.
    Uses the handler's built-in rotation logic which is more robust and easier
    to maintain than a custom doRollover implementation.
    """
    _ensure_dir_for_file(path)
    handler = TimedRotatingFileHandler(path, when=when, interval=interval, backupCount=backupCount, encoding='utf-8')
    # Default behavior is to append to the existing log file.
    # Rotation happens when 'when' occurs.
    if fmt:
        handler.setFormatter(fmt)
    if level is not None:
        handler.setLevel(level)
    return handler


def setup_logging():
    """
    Configure logging for the application and return (logger, info_handler, error_handler, warning_handler).
    This version uses standard TimedRotatingFileHandler to keep the logic simple and
    avoid fragile file-renaming on Windows.
    """
    # Select a format depending on environment for easier debugging in dev
    if os.getenv('ACH_ENV') == 'development':
        log_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(pathname)s:%(lineno)d')
    elif os.getenv('ACH_ENV') == 'production':
        log_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    else:
        log_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s')

    error_log_path = os.getenv('ERROR_LOG_FILE_PATH', "./logs/ACH_media_import_errors.log")
    warning_log_path = os.getenv('WARNING_LOG_FILE_PATH', "./logs/ACH_media_import_warnings.log")
    if os.getenv('WARING_LOG_FILE_PATH'):  # Fix typo in .env if present
        warning_log_path = os.getenv('WARING_LOG_FILE_PATH')
    info_log_path = os.getenv('INFO_LOG_FILE_PATH', "./logs/ACH_media_import_info.log")

    # Create three handlers: info (all), warning (warning+), error (error+)
    info_handler = _create_timed_handler(info_log_path, level=logging.INFO, fmt=log_formatter, backupCount=int(os.getenv('LOG_BACKUP_COUNT', '7')))
    warning_handler = _create_timed_handler(warning_log_path, level=logging.WARNING, fmt=log_formatter, backupCount=int(os.getenv('LOG_BACKUP_COUNT', '7')))
    error_handler = _create_timed_handler(error_log_path, level=logging.ERROR, fmt=log_formatter, backupCount=int(os.getenv('LOG_BACKUP_COUNT', '7')))

    console_handler = logging.StreamHandler()
    console_handler.setFormatter(log_formatter)

    # Configure root logger explicitly
    root_logger = logging.getLogger()
    root_logger.setLevel(logging.INFO)
    # Clear existing handlers to avoid duplicate logs when unit tests or reloads occur
    root_logger.handlers = []
    root_logger.addHandler(info_handler)
    root_logger.addHandler(warning_handler)
    root_logger.addHandler(error_handler)
    root_logger.addHandler(console_handler)

    # Return the root logger and handlers (so callers can do manual rollovers if they truly need to)
    return root_logger, info_handler, error_handler, warning_handler