import 'package:firebase_core/firebase_core.dart';
import 'package:logger/logger.dart';

const _maxRetries = 3;
const _baseDelayMs = 1000;

/// Retries [fn] when it throws FirebaseException with code 'unavailable'.
/// Firestore transient errors often succeed on retry with backoff.
Future<T> retryOnFirestoreUnavailable<T>(Future<T> Function() fn) async {
  var attempt = 0;
  while (true) {
    try {
      return await fn();
    } catch (e) {
      final isUnavailable = e is FirebaseException &&
          (e.code == 'unavailable' || e.code.contains('unavailable'));
      if (isUnavailable && attempt < _maxRetries) {
        attempt++;
        final delayMs = _baseDelayMs * (1 << (attempt - 1));
        Logger().w(
          'Firestore unavailable (attempt $attempt/$_maxRetries), retrying in ${delayMs}ms',
        );
        await Future.delayed(Duration(milliseconds: delayMs));
      } else {
        rethrow;
      }
    }
  }
}
