"""WebSocket connection manager for real-time notifications."""
import asyncio
import json
from datetime import datetime, timezone
from typing import Set
from fastapi import WebSocket


class ConnectionManager:
    """Manages WebSocket connections and broadcasts."""

    def __init__(self):
        self._connections: Set[WebSocket] = set()
        self._lock = asyncio.Lock()

    async def connect(self, websocket: WebSocket) -> None:
        """Accept and track a new WebSocket connection."""
        await websocket.accept()
        async with self._lock:
            self._connections.add(websocket)

        # Send initial connected event
        await self._send_to_client(websocket, {
            "type": "event",
            "event": "connected",
            "data": {"message": "Connected to Dangerous Pi event stream"},
            "timestamp": datetime.now(timezone.utc).isoformat()
        })

    async def disconnect(self, websocket: WebSocket) -> None:
        """Remove a disconnected WebSocket."""
        async with self._lock:
            self._connections.discard(websocket)

    async def broadcast(self, event_type: str, data: dict) -> None:
        """Broadcast an event to all connected clients."""
        message = {
            "type": "event",
            "event": event_type,
            "data": data,
            "timestamp": datetime.now(timezone.utc).isoformat()
        }

        async with self._lock:
            dead_connections: Set[WebSocket] = set()
            for connection in self._connections:
                try:
                    await asyncio.wait_for(
                        self._send_to_client(connection, message),
                        timeout=5.0
                    )
                except asyncio.TimeoutError:
                    dead_connections.add(connection)
                except Exception:
                    dead_connections.add(connection)

            # Remove dead connections
            self._connections -= dead_connections

    async def _send_to_client(self, websocket: WebSocket, message: dict) -> None:
        """Send a message to a specific client."""
        await websocket.send_json(message)

    @property
    def connection_count(self) -> int:
        """Return number of active connections."""
        return len(self._connections)


# Global singleton instance
ws_manager = ConnectionManager()
