// lib/services/review_service.dart
import '../data/save_repository.dart';
import 'review_prompt_policy.dart';

/// A thin seam over the in_app_review plugin so unit tests never reach platform
/// channels. The release wiring uses [StoreReviewer] (see store_reviewer.dart),
/// which forwards to the real InAppReview instance.
abstract class Reviewer {
  Future<bool> isAvailable();
  Future<void> requestReview();
}

/// Decides and triggers the native "rate this app" sheet at most once, on a
/// genuine high point. Holds no plugin dependency — that lives behind
/// [Reviewer] — so the decision path is fully unit-testable.
class ReviewService {
  ReviewService({
    required SaveRepository save,
    required Reviewer reviewer,
    ReviewPromptPolicy policy = const ReviewPromptPolicy(),
  })  : _save = save,
        _reviewer = reviewer,
        _policy = policy;

  final SaveRepository _save;
  final Reviewer _reviewer;
  final ReviewPromptPolicy _policy;

  /// Call right after a stage win has been recorded to progress. Asks for a
  /// review if the policy allows and the store can show the sheet, then never
  /// again. The one-shot flag is only burned once the sheet is actually
  /// requested, so an unavailable store retries on a later win. Every failure
  /// is swallowed — a review prompt must never break gameplay.
  Future<void> maybeRequestAfterWin({required int stars}) async {
    final allowed = _policy.shouldRequest(
      alreadyRequested: _save.reviewRequested,
      won: true,
      stars: stars,
      totalStagesWon: _save.stagesClearedCount,
    );
    if (!allowed) return;
    try {
      if (await _reviewer.isAvailable()) {
        await _reviewer.requestReview();
        await _save.markReviewRequested();
      }
    } catch (_) {/* never break gameplay over a review prompt */}
  }
}
