# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""
Callback registry for decoupled event notifications.

Allows interfaces to notify about changes without knowing about features.
Features can register callbacks to be notified when automations change.
"""

import logging
from typing import Callable, List, Dict, Any

logger = logging.getLogger(__name__)


class CallbackRegistry:
    """Registry for callbacks that can be triggered by interfaces without knowing about features."""
    
    def __init__(self):
        self._callbacks: Dict[str, List[Callable]] = {}
    
    def register(self, event_type: str, callback: Callable):
        """Register a callback for a specific event type.
        
        Args:
            event_type: Type of event (e.g., 'automation.changed')
            callback: Sync callback function
        """
        if event_type not in self._callbacks:
            self._callbacks[event_type] = []
        self._callbacks[event_type].append(callback)
        logger.debug(f"Registered callback for event type: {event_type}")
    
    def unregister(self, event_type: str, callback: Callable):
        """Unregister a callback for a specific event type."""
        if event_type in self._callbacks:
            try:
                self._callbacks[event_type].remove(callback)
                logger.debug(f"Unregistered callback for event type: {event_type}")
            except ValueError:
                logger.warning(f"Callback not found for event type: {event_type}")
    
    def trigger(self, event_type: str, *args, **kwargs):
        """Trigger all registered callbacks for an event type.
        
        Args:
            event_type: Type of event to trigger
            *args, **kwargs: Arguments to pass to callbacks
        """
        if event_type not in self._callbacks:
            return
        
        callbacks = self._callbacks[event_type].copy()  # Copy to avoid modification during iteration
        
        for callback in callbacks:
            try:
                callback(*args, **kwargs)
            except Exception as e:
                logger.error(f"Error executing callback for {event_type}: {str(e)}", exc_info=True)
    
    def hasCallbacks(self, event_type: str) -> bool:
        """Check if there are any callbacks registered for an event type."""
        return event_type in self._callbacks and len(self._callbacks[event_type]) > 0


# Global singleton instance
callbackRegistry = CallbackRegistry()
