"""
Function registry for dynamic AI function discovery
Lazy loading - functions are only imported when actually needed
"""
import logging
from typing import Dict, Type, Optional
from igny8_core.ai.base import BaseAIFunction

logger = logging.getLogger(__name__)

_FUNCTION_REGISTRY: Dict[str, Type[BaseAIFunction]] = {}
_FUNCTION_LOADERS: Dict[str, callable] = {}


def register_function(name: str, function_class: Type[BaseAIFunction]):
    """Register an AI function"""
    if not issubclass(function_class, BaseAIFunction):
        raise ValueError(f"{function_class} must inherit from BaseAIFunction")
    
    _FUNCTION_REGISTRY[name] = function_class
    logger.info(f"Registered AI function: {name}")


def register_lazy_function(name: str, loader_func: callable):
    """Register a lazy loader for a function - will only import when needed"""
    _FUNCTION_LOADERS[name] = loader_func


def get_function(name: str) -> Optional[Type[BaseAIFunction]]:
    """Get function class by name - lazy loads if not already registered"""
    # Check if already loaded
    if name in _FUNCTION_REGISTRY:
        return _FUNCTION_REGISTRY[name]
    
    # Try lazy loading
    if name in _FUNCTION_LOADERS:
        try:
            loader = _FUNCTION_LOADERS[name]
            fn_class = loader()
            _FUNCTION_REGISTRY[name] = fn_class
            logger.info(f"Lazy loaded AI function: {name}")
            return fn_class
        except Exception as e:
            logger.error(f"Failed to lazy load function {name}: {e}", exc_info=True)
            return None
    
    return None


def list_functions() -> list:
    """List all registered functions"""
    return list(_FUNCTION_REGISTRY.keys())


def get_function_instance(name: str) -> Optional[BaseAIFunction]:
    """Get function instance by name - lazy loads if needed"""
    # Resolve alias first to support legacy function names
    try:
        from igny8_core.ai.settings import FUNCTION_ALIASES
    except ImportError:
        FUNCTION_ALIASES = {}
    
    actual_name = FUNCTION_ALIASES.get(name, name)
    
    fn_class = get_function(actual_name)
    if fn_class:
        return fn_class()
    return None


# Register lazy loaders - functions are only imported when actually called
def _load_auto_cluster():
    """Lazy loader for auto_cluster function"""
    from igny8_core.ai.functions.auto_cluster import AutoClusterFunction
    return AutoClusterFunction

def _load_generate_ideas():
    """Lazy loader for generate_ideas function"""
    from igny8_core.ai.functions.generate_ideas import GenerateIdeasFunction
    return GenerateIdeasFunction

def _load_generate_content():
    """Lazy loader for generate_content function"""
    from igny8_core.ai.functions.generate_content import GenerateContentFunction
    return GenerateContentFunction

def _load_generate_images():
    """Lazy loader for generate_images function"""
    from igny8_core.ai.functions.generate_images import GenerateImagesFunction
    return GenerateImagesFunction

def _load_generate_image_prompts():
    """Lazy loader for generate_image_prompts function"""
    from igny8_core.ai.functions.generate_image_prompts import GenerateImagePromptsFunction
    return GenerateImagePromptsFunction

register_lazy_function('auto_cluster', _load_auto_cluster)
register_lazy_function('generate_ideas', _load_generate_ideas)
register_lazy_function('generate_content', _load_generate_content)
register_lazy_function('generate_images', _load_generate_images)
register_lazy_function('generate_image_prompts', _load_generate_image_prompts)

