from typing import Dict, Set
from fastapi import WebSocket
import json
from datetime import datetime
from jose import jwt, JWTError
from utility.auth_token import verify_token

SECRET_KEY = "ton_secret_key"
ALGORITHM = "HS256"

class ConnectionManager:
    """Gestionnaire de connexions WebSocket avec gestion du token expiré"""
    
    def __init__(self):
        self.active_connections: Dict[str, Set[WebSocket]] = {
            "mobile": set(),
            "admin": set(),
        }
        self.config_versions: Dict[str, dict] = {}

    async def connect(self, websocket: WebSocket, token: str, client_type: str = "mobile"):
        """Accepter une nouvelle connexion WebSocket et vérifier le token"""
        # Vérifier le token avant d'accepter
        try:
            if not self.verify_token(token):
                await websocket.close(code=401, reason="Token expired")
                return
        except JWTError as e:
            print("Erreur JWT:", e)
            await websocket.close(code=400, reason="Invalid token")
            return

        await websocket.accept()
        if client_type not in self.active_connections:
            self.active_connections[client_type] = set()
        self.active_connections[client_type].add(websocket)
        print(f"✅ Nouvelle connexion {client_type}: {len(self.active_connections[client_type])} clients connectés")
    
    def disconnect(self, websocket: WebSocket, client_type: str = "mobile"):
        if client_type in self.active_connections:
            self.active_connections[client_type].discard(websocket)
            print(f"❌ Déconnexion {client_type}: {len(self.active_connections[client_type])} clients restants")

    async def send_personal_message(self, message: str, websocket: WebSocket):
        try:
            await websocket.send_text(message)
        except Exception as e:
            print(f"Erreur lors de l'envoi du message: {e}")

    async def broadcast_to_mobile(self, message: dict):
        disconnected = set()
        for connection in self.active_connections.get("mobile", set()):
            try:
                await connection.send_json(message)
            except Exception as e:
                print(f"Erreur lors de la diffusion: {e}")
                disconnected.add(connection)
        for conn in disconnected:
            self.disconnect(conn, "mobile")

    async def notify_config_update(self, config_type: str, config_data: dict):
        version = datetime.now().isoformat()
        self.config_versions[config_type] = {
            "version": version,
            "data": config_data,
            "updated_at": version
        }
        notification = {
            "type": "config_update",
            "config_type": config_type,
            "version": version,
            "data": config_data,
            "timestamp": version,
            "action": "reload"
        }
        await self.broadcast_to_mobile(notification)
        print(f"📢 Configuration '{config_type}' mise à jour et diffusée à {len(self.active_connections.get('mobile', set()))} clients mobiles")


    # Les autres méthodes de notification (advertisement, commission, etc.) restent inchangées
    async def notify_advertisement_update(self, ad_data: dict, action: str = "create"):
        notification = {
            "type": "advertisement_update",
            "action": action,
            "data": ad_data,
            "timestamp": datetime.now().isoformat()
        }
        await self.broadcast_to_mobile(notification)
        print(f"📢 Publicité {action}: diffusée à {len(self.active_connections.get('mobile', set()))} clients")
