import logging
import pkgutil
import importlib

from wurker.settings import conf
from wurker.util import init_logger
import wurker.bees.dispatchers as dispatchers_pkg

logger = init_logger()


def load_callbacks():
    """
    Discover and register dispatcher callbacks from the wurker.bees.dispatchers namespace,
    including any plugins loaded via load_plugins().
    """

    callbacks = {}
    for finder, name, ispkg in pkgutil.iter_modules(dispatchers_pkg.__path__):
        if not name.startswith('cb_'):
            continue

        module_name = f"{dispatchers_pkg.__name__}.{name}"
        try:
            module = importlib.import_module(module_name)
            logger.log(f"Loaded dispatcher module: {module_name}", prefix="load_callbacks", level="debug")
        except Exception as e:
            logger.log(f"Error loading dispatcher module: {module_name}: {e}",
                       prefix="load_callbacks", level="error")
            continue

        if not hasattr(module, 'callback'):
            raise Exception(f"Dispatcher module missing 'callback' function: {module_name!r}")

        callbacks[name] = module.callback

    return callbacks


def run(slug:str="", **kwargs):
    """
    Wurker Queen Drone Dispatch
    ---------------------------
    Implement input reader callbacks in the 'bees.dispatchers' namespace.
    Dispatcher modules must be named 'cb_<slug>.py' and define a 'callback(**kwargs)' function.

    :param slug: The dispatcher slug to invoke (e.g. 'my_task')
    :param **kwargs: Arguments passed to the callback
    :return: Integer exit code
    """

    logger = init_logger()

    if not conf.is_queen:
        logger.log("This Wurker is not a Queen", level=logging.ERROR, prefix="dispatch.run")
        return 1

    # Reload callbacks to include any new plugins
    dispatchers_pkg.callbacks = load_callbacks()

    module_slug = f"cb_{slug}"
    if module_slug not in dispatchers_pkg.callbacks:
        logger.log(f"Wurker Drone Dispatcher callback does not exist: '{module_slug}'", prefix="dispatch.run")
        return 2

    try:
        return dispatchers_pkg.callbacks[module_slug](**kwargs)
    except Exception as e:
        logger.log(f"Exception in dispatcher callback '{module_slug}': {e}",
                   prefix="dispatch.run", level=logging.ERROR, exception=True)
        return 3
