/**
 * @ai-summary Google Maps API circuit breaker
 * @ai-context Wraps Google Maps API calls with resilience pattern
 */

import CircuitBreaker from 'opossum';
import { logger } from '../../../../core/logging/logger';

/**
 * Google Maps API Circuit Breaker Configuration
 * Prevents cascading failures when Google Maps API is unavailable
 *
 * Configuration:
 * - timeout: 10s max wait for API response
 * - errorThresholdPercentage: 50% error rate triggers open
 * - resetTimeout: 30s before attempting recovery
 * - name: identifier for logging
 */
export function createGoogleMapsCircuitBreaker<T>(
  asyncFn: () => Promise<T>,
  operationName: string
): CircuitBreaker {
  const breaker = new CircuitBreaker(asyncFn, {
    timeout: 10000, // 10 seconds
    errorThresholdPercentage: 50,
    resetTimeout: 30000, // 30 seconds
    name: `google-maps-${operationName}`,
    volumeThreshold: 10, // Minimum requests before opening
    rollingCountTimeout: 10000 // Window for counting requests
  });

  // Log circuit state changes for monitoring
  breaker.on('open', () => {
    logger.warn(`Circuit breaker opened for Google Maps ${operationName}`);
  });

  breaker.on('halfOpen', () => {
    logger.info(`Circuit breaker half-open for Google Maps ${operationName}`);
  });

  breaker.on('close', () => {
    logger.info(`Circuit breaker closed for Google Maps ${operationName}`);
  });

  return breaker;
}

/**
 * Execute function through circuit breaker
 * Falls back to null if circuit is open or function fails
 */
export async function executeWithCircuitBreaker<T>(
  breaker: CircuitBreaker,
  asyncFn: () => Promise<T>
): Promise<T | null> {
  try {
    return (await breaker.fire(asyncFn)) as T;
  } catch (error) {
    logger.error('Circuit breaker execution failed', {
      error: error instanceof Error ? error.message : String(error),
      brearerName: breaker.name
    });
    return null;
  }
}
