import logging
from typing import Any

from mizan._vendor.app_visitor import DjangoAppVisitor, get_members

from mizan_core.registry import register, get_function
from mizan_core.client.function import ServerFunction

logger = logging.getLogger(__name__)


class _RegisterServerFunctions:
    def on_module(
        self, app_name: str, path_parts: list[str], members: list[tuple[str, Any]]
    ) -> None:
        for name, member in members:
            # Register ServerFunction subclasses
            if (
                isinstance(member, type)
                and issubclass(member, ServerFunction)
                and member is not ServerFunction
                and hasattr(member, "__name__")
            ):
                # Use the function name as registration name
                fn_name = getattr(member, "name", None) or member.__name__

                # Skip already registered (idempotent)
                if get_function(fn_name) is member:
                    continue

                try:
                    register(member, fn_name)
                except ValueError:
                    logger.warning(
                        "Server function name %r already registered with a "
                        "different class; skipping %s.%s",
                        fn_name,
                        member.__module__,
                        member.__qualname__,
                    )


# Scans <app>/<layer>.py and <app>/<layer>/**/*.py under apps_root
def mizan_clients(apps_root: str, layer: str = "clients") -> None:
    visitor = DjangoAppVisitor(layer=layer, apps_root=apps_root)
    visitor.visit(_RegisterServerFunctions())


# Registers server functions from one module path, e.g. 'mizan.jwt.functions'
def mizan_module(module_path: str) -> None:
    members = get_members(module_path)
    handler = _RegisterServerFunctions()
    handler.on_module("", [], members)
