"""Backend registry and connection utilities."""

import importlib
import os
from typing import Any

from amsdal_mail.backends.base import BaseEmailBackend

# Registry of available backends
BACKENDS: dict[str, str] = {
    'console': 'amsdal_mail.backends.console.ConsoleBackend',
    'dummy': 'amsdal_mail.backends.dummy.DummyBackend',
    'ses': 'amsdal_mail.backends.ses.SESBackend',
    'smtp': 'amsdal_mail.backends.smtp.SMTPBackend',
}


def import_string(dotted_path: str) -> Any:
    """
    Import a class from a dotted module path.

    Args:
        dotted_path: Full dotted path to class (e.g., 'package.module.ClassName')

    Returns:
        The imported class

    Raises:
        ImportError: If the module or class cannot be imported
    """
    try:
        module_path, class_name = dotted_path.rsplit('.', 1)
    except ValueError as e:
        msg = f"'{dotted_path}' doesn't look like a module path"
        raise ImportError(msg) from e

    try:
        module = importlib.import_module(module_path)
    except ImportError as e:
        msg = f"Module '{module_path}' could not be imported"
        raise ImportError(msg) from e

    try:
        return getattr(module, class_name)
    except AttributeError as e:
        msg = f"Module '{module_path}' does not define a '{class_name}' class"
        raise ImportError(msg) from e


def get_connection(
    backend: str | None = None,
    *,
    fail_silently: bool = False,
    **kwargs: Any,
) -> BaseEmailBackend:
    """
    Load an email backend and return an instance.

    Args:
        backend: Backend name (from BACKENDS registry) or full dotted path.
                 If None, uses AMSDAL_EMAIL_BACKEND environment variable.
                 Defaults to 'console' if not specified.
        fail_silently: If True, suppress exceptions in send operations
        **kwargs: Backend-specific configuration options

    Returns:
        An instance of the specified backend

    Raises:
        ImportError: If the backend cannot be imported
        ConfigurationError: If the backend is misconfigured

    Examples:
        >>> # Use registered backend name
        >>> conn = get_connection('smtp', host='smtp.gmail.com', port=587)

        >>> # Use full dotted path
        >>> conn = get_connection('myapp.backends.CustomBackend')

        >>> # Use environment variable
        >>> os.environ['AMSDAL_EMAIL_BACKEND'] = 'smtp'
        >>> conn = get_connection()
    """
    # Resolve backend name
    if backend is None:
        backend = os.environ.get('AMSDAL_EMAIL_BACKEND', 'console')

    # Check if it's a registered backend name
    if backend in BACKENDS:
        backend = BACKENDS[backend]

    # Import and instantiate the backend
    backend_cls = import_string(backend)

    return backend_cls(fail_silently=fail_silently, **kwargs)


__all__ = [
    'BACKENDS',
    'BaseEmailBackend',
    'get_connection',
    'import_string',
]
