"""
Gestionnaire WebSocket pour notifications temps réel
"""
from fastapi import WebSocket
from typing import List, Dict, Any
import json
from datetime import datetime


class WebSocketManager:
    """Gestionnaire de connexions WebSocket"""

    def __init__(self):
        """Initialise le gestionnaire"""
        self.active_connections: List[WebSocket] = []

    async def connect(self, websocket: WebSocket):
        """
        Accepte une nouvelle connexion WebSocket

        Args:
            websocket: Instance WebSocket
        """
        await websocket.accept()
        self.active_connections.append(websocket)
        print(f"[{datetime.now()}] Nouvelle connexion WebSocket. Total: {len(self.active_connections)}")

    def disconnect(self, websocket: WebSocket):
        """
        Déconnecte un client WebSocket

        Args:
            websocket: Instance WebSocket à déconnecter
        """
        if websocket in self.active_connections:
            self.active_connections.remove(websocket)
            print(f"[{datetime.now()}] Déconnexion WebSocket. Total: {len(self.active_connections)}")

    async def send_personal_message(self, message: str, websocket: WebSocket):
        """
        Envoie un message à un client spécifique

        Args:
            message: Message à envoyer
            websocket: Client destinataire
        """
        try:
            await websocket.send_text(message)
        except Exception as e:
            print(f"Erreur envoi message personnel: {e}")

    async def broadcast(self, message: Dict[str, Any]):
        """
        Diffuse un message à tous les clients connectés

        Args:
            message: Dictionnaire du message (sera converti en JSON)
        """
        # Ajouter un timestamp
        message["timestamp"] = datetime.now().isoformat()

        json_message = json.dumps(message)

        # Liste des connexions à supprimer (déconnectées)
        disconnected = []

        for connection in self.active_connections:
            try:
                await connection.send_text(json_message)
            except Exception as e:
                print(f"Erreur broadcast: {e}")
                disconnected.append(connection)

        # Nettoyer les connexions mortes
        for conn in disconnected:
            self.disconnect(conn)

    async def broadcast_scan_start(self):
        """Notifie le début d'un scan"""
        await self.broadcast({
            "type": "scan_start",
            "message": "Scan réseau démarré"
        })

    async def broadcast_scan_complete(self, stats: Dict[str, int]):
        """
        Notifie la fin d'un scan avec statistiques

        Args:
            stats: Statistiques du scan (total, online, offline, etc.)
        """
        await self.broadcast({
            "type": "scan_complete",
            "message": "Scan réseau terminé",
            "stats": stats
        })

    async def broadcast_ip_update(self, ip_data: Dict[str, Any]):
        """
        Notifie un changement d'état d'IP

        Args:
            ip_data: Données de l'IP mise à jour
        """
        await self.broadcast({
            "type": "ip_update",
            "data": ip_data
        })

    async def broadcast_new_ip(self, ip_data: Dict[str, Any]):
        """
        Notifie la détection d'une nouvelle IP

        Args:
            ip_data: Données de la nouvelle IP
        """
        await self.broadcast({
            "type": "new_ip",
            "data": ip_data,
            "message": f"Nouvelle IP détectée: {ip_data.get('ip')}"
        })

    async def broadcast_scan_progress(self, progress_data: Dict[str, Any]):
        """
        Notifie la progression d'un scan en cours

        Args:
            progress_data: Données de progression (current, total, ip)
        """
        await self.broadcast({
            "type": "scan_progress",
            "current": progress_data.get("current"),
            "total": progress_data.get("total"),
            "ip": progress_data.get("ip")
        })

    async def broadcast_scan_log(self, message: str):
        """Diffuse une ligne de log de scan"""
        await self.broadcast({
            "type": "scan_log",
            "message": message
        })


# Instance globale du gestionnaire WebSocket
ws_manager = WebSocketManager()
