import 'package:flutter/foundation.dart'; /// Where events land. Phase 4 ships the debug logger; the Firebase backend /// plugs in here after the owner runs flutterfire configure. abstract class AnalyticsBackend { void logEvent(String name, Map params); } class DebugAnalyticsBackend implements AnalyticsBackend { @override void logEvent(String name, Map params) { debugPrint('[analytics] $name $params'); } } /// Typed event surface. Booleans are sent as 0/1 ints so every backend /// (GA4 included) aggregates them the same way. class AnalyticsService { AnalyticsService(this._backend); final AnalyticsBackend _backend; void stageStart({required String seasonId, required String stageId}) { _backend.logEvent('stage_start', { 'season_id': seasonId, 'stage_id': stageId, }); } void stageEnd({ required String seasonId, required String stageId, required bool won, required int stars, required int score, required int movesUsed, }) { _backend.logEvent('stage_end', { 'season_id': seasonId, 'stage_id': stageId, 'won': won ? 1 : 0, 'stars': stars, 'score': score, 'moves_used': movesUsed, }); } void endlessStart() => _backend.logEvent('endless_start', const {}); void endlessEnd({required int score, required bool isNewBest}) { _backend.logEvent('endless_end', { 'score': score, 'new_best': isNewBest ? 1 : 0, }); } void rescueUsed({required String type}) { _backend.logEvent('rescue_used', {'type': type}); } void tutorialFinished({required bool skipped}) { _backend.logEvent('tutorial_finished', {'skipped': skipped ? 1 : 0}); } void boosterUsed({required String type}) => _backend.logEvent('booster_used', {'type': type}); void boosterGranted( {required String type, required int count, required String source}) => _backend.logEvent( 'booster_granted', {'type': type, 'count': count, 'source': source}); void dailyRewardClaimed({required int day, required bool doubled}) => _backend.logEvent( 'daily_reward_claimed', {'day': day, 'doubled': doubled ? 1 : 0}); }