"""Local event bus — replaces Redis pub/sub.

Simple asyncio-based event system for internal metrics and logging.
In the MCP context there is no WebSocket dashboard consuming events,
so this is primarily fire-and-forget for logging and future extensibility.
"""

import asyncio
import json
import logging
from typing import Callable, Any
from datetime import datetime, timezone

logger = logging.getLogger(__name__)

# channel -> list of async callbacks
_subscribers: dict[str, list[Callable]] = {}

# Recent events buffer (for status queries)
_recent_events: list[dict] = []
MAX_RECENT_EVENTS = 100

CHANNEL = "soagila:metrics"  # Default channel name (matching Redis original)


async def publish_event(channel: str, message: str) -> None:
    """Publish an event to subscribers.

    Drop-in replacement for redis_client.publish_event().
    """
    # Store in recent buffer
    try:
        event_data = json.loads(message) if isinstance(message, str) else message
    except (json.JSONDecodeError, TypeError):
        event_data = {"raw": str(message)}

    event_data["_timestamp"] = datetime.now(timezone.utc).isoformat()
    event_data["_channel"] = channel

    _recent_events.append(event_data)
    if len(_recent_events) > MAX_RECENT_EVENTS:
        _recent_events.pop(0)

    # Notify subscribers
    callbacks = _subscribers.get(channel, [])
    for callback in callbacks:
        try:
            asyncio.create_task(callback(message))
        except Exception as e:
            logger.error(f"Event callback error on {channel}: {e}")

    logger.debug(f"Event published to {channel}: {message[:100]}")


def subscribe(channel: str, callback: Callable) -> None:
    """Subscribe to events on a channel."""
    if channel not in _subscribers:
        _subscribers[channel] = []
    _subscribers[channel].append(callback)


def unsubscribe(channel: str, callback: Callable) -> None:
    """Unsubscribe from a channel."""
    if channel in _subscribers:
        _subscribers[channel] = [cb for cb in _subscribers[channel] if cb != callback]


def get_recent_events(limit: int = 50) -> list[dict]:
    """Get recent events for status/debug."""
    return _recent_events[-limit:]


def clear_events() -> None:
    """Clear all recent events."""
    _recent_events.clear()
