"""
Gestionnaire de retry centralisé - NOUVEAU FICHIER
"""
import time
import asyncio
from typing import Callable, Optional, Any
from ...monitoring.logger import logger


class RetryManager:
    """
    Gestionnaire centralisé des tentatives de reconnexion
    
    Évite la duplication entre connection.py et client.py
    """
    
    def __init__(self, max_attempts: int = 5, base_delay: float = 2.0, max_delay: float = 60.0):
        self.max_attempts = max_attempts
        self.base_delay = base_delay
        self.max_delay = max_delay
        self.current_attempts = 0
    
    def retry_with_backoff(self, 
                          operation: Callable[[], bool], 
                          operation_name: str = "operation") -> bool:
        """
        Exécute une opération avec retry et backoff exponentiel
        
        Args:
            operation: Fonction qui retourne True en cas de succès
            operation_name: Nom pour les logs
            
        Returns:
            bool: True si l'opération a réussi
        """
        self.current_attempts = 0
        
        for attempt in range(1, self.max_attempts + 1):
            self.current_attempts = attempt
            
            try:
                logger('debug', f"[RETRY] {operation_name} - tentative {attempt}/{self.max_attempts}")
                
                if operation():
                    logger('info', f"[RETRY] {operation_name} réussi (tentative {attempt})")
                    self.current_attempts = 0
                    return True
                    
            except Exception as e:
                logger('warning', f"[RETRY] {operation_name} échoué (tentative {attempt}): {e}")
            
            # Backoff exponentiel avant retry
            if attempt < self.max_attempts:
                delay = min(self.base_delay * (2 ** (attempt - 1)), self.max_delay)
                logger('debug', f"[RETRY] Attente {delay:.1f}s avant tentative suivante...")
                time.sleep(delay)
        
        logger('error', f"[RETRY] {operation_name} échoué après {self.max_attempts} tentatives")
        return False
    
    def reset(self):
        """Remet à zéro le compteur de tentatives"""
        self.current_attempts = 0
    
    @property
    def has_failed_max_attempts(self) -> bool:
        """True si le nombre max de tentatives a été atteint"""
        return self.current_attempts >= self.max_attempts