import 'package:logging/logging.dart';

/// Circuit breaker pattern implementation for authentication service failures
class AuthCircuitBreaker {
  static final _logger = Logger('service.auth_circuit_breaker');
  
  static int _failureCount = 0;
  static DateTime? _lastFailure;
  static const int _failureThreshold = 3;
  static const Duration _recoveryTime = Duration(minutes: 5);
  
  /// Returns true if the circuit breaker is open (blocking operations)
  static bool get isOpen {
    if (_failureCount < _failureThreshold) return false;
    if (_lastFailure == null) return false;
    
    final isOpen = DateTime.now().difference(_lastFailure!) < _recoveryTime;
    if (isOpen) {
      _logger.warning('Circuit breaker is OPEN. Failure count: $_failureCount, last failure: $_lastFailure');
    }
    return isOpen;
  }
  
  /// Returns true if the circuit breaker is in half-open state (allowing test requests)
  static bool get isHalfOpen {
    if (_failureCount < _failureThreshold) return false;
    if (_lastFailure == null) return false;
    
    return DateTime.now().difference(_lastFailure!) >= _recoveryTime;
  }
  
  /// Executes an operation with circuit breaker protection
  static Future<T> execute<T>(Future<T> Function() operation) async {
    if (isOpen) {
      final timeSinceFailure = _lastFailure != null 
        ? DateTime.now().difference(_lastFailure!)
        : Duration.zero;
      final timeUntilRecovery = _recoveryTime - timeSinceFailure;
      
      _logger.warning('Circuit breaker blocking operation. Recovery in: ${timeUntilRecovery.inSeconds}s');
      throw Exception('Auth service temporarily unavailable. Try again in ${timeUntilRecovery.inMinutes} minutes.');
    }
    
    try {
      _logger.fine('Executing operation through circuit breaker');
      final result = await operation();
      _reset();
      return result;
    } catch (e) {
      _recordFailure();
      rethrow;
    }
  }
  
  /// Records a failure and updates the circuit breaker state
  static void _recordFailure() {
    _failureCount++;
    _lastFailure = DateTime.now();
    _logger.warning('Auth circuit breaker recorded failure #$_failureCount at $_lastFailure');
    
    if (_failureCount >= _failureThreshold) {
      _logger.severe('Auth circuit breaker OPENED after $_failureCount failures');
    }
  }
  
  /// Resets the circuit breaker to closed state
  static void _reset() {
    if (_failureCount > 0) {
      _logger.info('Auth circuit breaker CLOSED - resetting failure count from $_failureCount to 0');
    }
    _failureCount = 0;
    _lastFailure = null;
  }
  
  /// Manual reset (for testing or administrative purposes)
  static void manualReset() {
    _logger.info('Auth circuit breaker manually reset');
    _reset();
  }
  
  /// Get current status for debugging
  static Map<String, dynamic> getStatus() {
    return {
      'failureCount': _failureCount,
      'lastFailure': _lastFailure?.toIso8601String(),
      'isOpen': isOpen,
      'isHalfOpen': isHalfOpen,
      'threshold': _failureThreshold,
      'recoveryTime': _recoveryTime.inSeconds,
    };
  }
}