"""Event constants and lightweight in-process event bus."""

from __future__ import annotations

from collections import defaultdict
import logging
from typing import Any, Callable

logger = logging.getLogger(__name__)


class NeurovaultEvents:
    MEMORY_INGESTED = "memory.ingested"
    MEMORY_DEDUPLICATED = "memory.deduplicated"
    MEMORY_FILTERED = "memory.filtered"
    MEMORY_RECALLED = "memory.recalled"
    MEMORY_DECAYED = "memory.decayed"
    MEMORY_PROMOTED = "memory.promoted"
    MEMORY_ARCHIVED = "memory.archived"
    ENTITY_DISCOVERED = "entity.discovered"
    ENTITY_CREATED = "entity.created"
    ENTITY_UPDATED = "entity.updated"
    RELATIONSHIP_FOUND = "relationship.found"
    RELATIONSHIP_CREATED = "relationship.created"
    INSIGHT_GENERATED = "insight.generated"
    CONSOLIDATION_STARTED = "consolidation.started"
    CONSOLIDATION_ENTITY_EXTRACTED = "consolidation.entity_extracted"
    CONSOLIDATION_RELATIONSHIP_FOUND = "consolidation.relationship_found"
    CONSOLIDATION_CLUSTER_FORMED = "consolidation.cluster_formed"
    CONSOLIDATION_INSIGHT_GENERATED = "consolidation.insight_generated"
    CONSOLIDATION_COMPLETED = "consolidation.completed"
    CONCEPT_HIERARCHY_ADDED = "concept.hierarchy_added"
    PREDICTION_SURFACED = "prediction.surfaced"
    PREDICTION_CALENDAR = "prediction.calendar"
    PEER_DISCOVERED = "peer.discovered"
    PEER_CONNECTED = "peer.connected"
    PEER_DISCONNECTED = "peer.disconnected"
    SYNC_STARTED = "sync.started"
    SYNC_COMPLETED = "sync.completed"
    SYNC_CONFLICT = "sync.conflict"
    SENSOR_STARTED = "sensor.started"
    SENSOR_STOPPED = "sensor.stopped"
    PLUGIN_LOADED = "plugin.loaded"
    PLUGIN_ERROR = "plugin.error"
    DAEMON_STARTED = "daemon.started"
    DAEMON_STOPPED = "daemon.stopped"


class EventBus:
    """Tiny pub/sub helper for local event consumers."""

    def __init__(self):
        self._handlers: dict[str, list[Callable[[dict[str, Any]], None]]] = defaultdict(list)

    def subscribe(self, event_name: str, handler: Callable[[dict[str, Any]], None]) -> None:
        self._handlers[event_name].append(handler)

    def emit(self, event_name: str, payload: dict[str, Any]) -> None:
        for handler in self._handlers.get(event_name, []):
            try:
                handler(payload)
            except Exception as exc:
                logger.debug("Event handler failed for %s: %s", event_name, exc)
                continue
