/// Pure-Dart interstitial gate. No plugin imports so the monetization rules
/// are unit-tested headlessly. The service layer feeds it lifecycle events
/// and asks [canShowInterstitial] before every stage-end interstitial.
class AdFrequencyPolicy {
  AdFrequencyPolicy({
    this.minStagesBetween = 3,
    this.minInterval = const Duration(seconds: 90),
    this.firstStagesProtected = 5,
  });

  final int minStagesBetween;
  final Duration minInterval;
  final int firstStagesProtected;

  int _totalStagesCompleted = 0;
  int _stagesSinceLastInterstitial = 0;
  bool _rewardedShownThisRound = false;
  DateTime? _lastInterstitialAt;

  /// A new stage attempt began (fresh round). Clears the per-round rewarded
  /// flag so last round's rewarded does not block this round's interstitial.
  void onRoundStart() => _rewardedShownThisRound = false;

  /// A stage finished (won or lost). Drives both counters.
  void onStageCompleted() {
    _totalStagesCompleted++;
    _stagesSinceLastInterstitial++;
  }

  /// The player watched a rewarded ad in the current round.
  void onRewardedShown() => _rewardedShownThisRound = true;

  /// An interstitial was actually shown. Resets the spacing counters.
  void onInterstitialShown(DateTime now) {
    _stagesSinceLastInterstitial = 0;
    _lastInterstitialAt = now;
  }

  bool canShowInterstitial(DateTime now) {
    if (_totalStagesCompleted <= firstStagesProtected) return false;
    if (_rewardedShownThisRound) return false;
    if (_stagesSinceLastInterstitial < minStagesBetween) return false;
    final last = _lastInterstitialAt;
    if (last != null && now.difference(last) < minInterval) return false;
    return true;
  }
}
