import importlib
import logging
from pathlib import Path
from fastapi import APIRouter, FastAPI
from typing import Callable, Dict, Any, List

logger = logging.getLogger(__name__)

class ModuleRegistry:
    """Core registry for DSCons Plug & Play Modular Architecture."""
    def __init__(self):
        self.modules: Dict[str, Any] = {}
        self.routers: List[APIRouter] = []
        
    def discover_and_register(self, app: FastAPI, modules_dir: str = "app/modules"):
        """Scans the modules directory, loads __init__.py, and extracts routers."""
        base_path = Path(modules_dir)
        if not base_path.exists():
            logger.warning(f"[REGISTRY] Directory {modules_dir} does not exist. Skipping.")
            return

        logger.info(f"[REGISTRY] Scanning for modules in {modules_dir}...")
        for module_path in base_path.iterdir():
            if module_path.is_dir() and (module_path / "__init__.py").exists():
                module_name = module_path.name
                if module_name.startswith("__"):
                    continue
                try:
                    # Dynamically import the module
                    import_path = f"{modules_dir.replace('/', '.')}.{module_name}"
                    module = importlib.import_module(import_path)
                    
                    self.modules[module_name] = module
                    logger.info(f"[REGISTRY] Loaded module: {module_name}")
                    
                    # If module exposes a setup function, call it
                    if hasattr(module, "setup_module") and isinstance(module.setup_module, Callable):
                        module.setup_module(app, self)
                    
                    # If module exposes a router, register it
                    if hasattr(module, "router") and isinstance(module.router, APIRouter):
                        self.routers.append(module.router)
                        app.include_router(module.router)
                        logger.info(f"[REGISTRY] Registered router for module: {module_name}")
                        
                except Exception as e:
                    logger.error(f"[REGISTRY] Failed to load module {module_name}: {e}", exc_info=True)

registry = ModuleRegistry()
