import 'dart:async';


class RelinkScheduler {
  RelinkScheduler({
    this.maxAttempts = 3,
    this.backoffs = const [
      Duration.zero,
      Duration(seconds: 2),
      Duration(seconds: 5),
    ],
  }) : assert(maxAttempts > 0),
       assert(backoffs.isNotEmpty);

  final int maxAttempts;
  final List<Duration> backoffs;

  int _attempts = 0;
  bool _pending = false;
  Timer? _backoffTimer;
  Timer? _sustainTimer;


  bool get pending => _pending;


  int get attempts => _attempts;


  bool schedule({
    required void Function(Duration delay) onRelink,
    required void Function() onGiveUp,
  }) {
    if (_pending) return false;


    _sustainTimer?.cancel();

    if (_attempts >= maxAttempts) {
      onGiveUp();
      return false;
    }
    final backoffIndex = _attempts.clamp(0, backoffs.length - 1);
    final delay = backoffs[backoffIndex];
    _attempts++;

    _pending = true;
    _backoffTimer?.cancel();
    _backoffTimer = Timer(delay, () {
      _pending = false;
      onRelink(delay);
    });
    return true;
  }


  void armSustain({Duration sustain = const Duration(seconds: 30)}) {
    _sustainTimer?.cancel();
    _sustainTimer = Timer(sustain, () => _attempts = 0);
  }


  void cancelPending() {
    _backoffTimer?.cancel();
    _pending = false;
  }


  void reset() => _attempts = 0;


  void dispose() {
    _backoffTimer?.cancel();
    _sustainTimer?.cancel();
    _pending = false;
  }
}
