import 'package:games_services/games_services.dart'; import 'dart:async'; import 'dart:io'; /// Manages Google Play Games Services integration class GooglePlayGamesManager { static GooglePlayGamesManager? _instance; static GooglePlayGamesManager get instance { _instance ??= GooglePlayGamesManager._internal(); return _instance!; } GooglePlayGamesManager._internal(); // Feature flag to enable/disable Google Play Games Services static const bool _isEnabled = false; // Set to true to enable Google Play Games bool _isInitialized = false; bool _isSignedIn = false; String? _playerId; String? _playerName; // Achievement IDs - These need to be configured in Google Play Console static const String achievementFirstBubble = 'achievement_first_bubble'; static const String achievement100Bubbles = 'achievement_100_bubbles'; static const String achievement1000Bubbles = 'achievement_1000_bubbles'; static const String achievement5000Bubbles = 'achievement_5000_bubbles'; static const String achievementZenMaster = 'achievement_zen_master'; static const String achievementSpeedDemon = 'achievement_speed_demon'; static const String achievementPerfectSession = 'achievement_perfect_session'; // Leaderboard IDs - These need to be configured in Google Play Console static const String leaderboardHighScore = 'leaderboard_high_score'; static const String leaderboardZenMode = 'leaderboard_zen_mode'; static const String leaderboardTotalBubbles = 'leaderboard_total_bubbles'; static const String leaderboardLongestSession = 'leaderboard_longest_session'; /// Initialize Google Play Games Services Future initialize() async { if (!_isEnabled) { print('Google Play Games Services is disabled via feature flag'); return false; } if (_isInitialized) return true; try { // Only available on Android if (!Platform.isAndroid) { print('Google Play Games Services only available on Android'); return false; } _isInitialized = true; return true; } catch (e) { print('Error initializing Google Play Games: $e'); return false; } } /// Sign in to Google Play Games Future signIn() async { if (!_isEnabled) { print('Google Play Games Services is disabled via feature flag'); return false; } if (!_isInitialized) { await initialize(); } try { final result = await GamesServices.signIn(); _isSignedIn = result != null && result.isNotEmpty; if (_isSignedIn) { _playerId = result; print('Successfully signed in to Google Play Games: $_playerId'); // Get player name try { final playerName = await GamesServices.getPlayerName(); _playerName = playerName; print('Player name: $_playerName'); } catch (e) { print('Could not get player name: $e'); } } return _isSignedIn; } catch (e) { print('Error signing in to Google Play Games: $e'); _isSignedIn = false; return false; } } /// Sign out from Google Play Games Future signOut() async { try { // Note: games_services package doesn't have a signOut method // We'll just reset our local state _isSignedIn = false; _playerId = null; _playerName = null; print('Successfully signed out from Google Play Games'); } catch (e) { print('Error signing out from Google Play Games: $e'); } } /// Check if signed in bool get isSignedIn => _isSignedIn; /// Check if Google Play Games is enabled via feature flag bool get isEnabled => _isEnabled; /// Get player ID String? get playerId => _playerId; /// Get player name String? get playerName => _playerName; /// Submit score to leaderboard Future submitScore(String leaderboardId, int score) async { if (!_isEnabled) { print('Google Play Games Services is disabled via feature flag'); return false; } if (!_isSignedIn) { print('Not signed in to Google Play Games'); return false; } try { await GamesServices.submitScore( score: Score( androidLeaderboardID: leaderboardId, value: score, ), ); print('Score $score submitted to leaderboard $leaderboardId'); return true; } catch (e) { print('Error submitting score: $e'); return false; } } /// Show leaderboards Future showLeaderboards() async { if (!_isEnabled) { print('Google Play Games Services is disabled via feature flag'); return; } if (!_isSignedIn) { print('Not signed in to Google Play Games'); return; } try { await GamesServices.showLeaderboards(); } catch (e) { print('Error showing leaderboards: $e'); } } /// Show specific leaderboard Future showLeaderboard(String leaderboardId) async { if (!_isEnabled) { print('Google Play Games Services is disabled via feature flag'); return; } if (!_isSignedIn) { print('Not signed in to Google Play Games'); return; } try { await GamesServices.showLeaderboards( androidLeaderboardID: leaderboardId, ); } catch (e) { print('Error showing leaderboard: $e'); } } /// Unlock achievement Future unlockAchievement(String achievementId) async { if (!_isEnabled) { print('Google Play Games Services is disabled via feature flag'); return false; } if (!_isSignedIn) { print('Not signed in to Google Play Games'); return false; } try { await GamesServices.unlock( achievement: Achievement( androidID: achievementId, ), ); print('Achievement $achievementId unlocked'); return true; } catch (e) { print('Error unlocking achievement: $e'); return false; } } /// Increment achievement (for incremental achievements) Future incrementAchievement(String achievementId, int steps) async { if (!_isEnabled) { print('Google Play Games Services is disabled via feature flag'); return false; } if (!_isSignedIn) { print('Not signed in to Google Play Games'); return false; } try { await GamesServices.increment( achievement: Achievement( androidID: achievementId, steps: steps, ), ); print('Achievement $achievementId incremented by $steps steps'); return true; } catch (e) { print('Error incrementing achievement: $e'); return false; } } /// Show achievements Future showAchievements() async { if (!_isEnabled) { print('Google Play Games Services is disabled via feature flag'); return; } if (!_isSignedIn) { print('Not signed in to Google Play Games'); return; } try { await GamesServices.showAchievements(); } catch (e) { print('Error showing achievements: $e'); } } /// Check achievement-related milestones for bubble popping Future checkBubbleAchievements(int totalBubbles) async { if (!_isEnabled) return; if (!_isSignedIn) return; // First bubble achievement if (totalBubbles >= 1) { await unlockAchievement(achievementFirstBubble); } // 100 bubbles achievement if (totalBubbles >= 100) { await unlockAchievement(achievement100Bubbles); } // 1000 bubbles achievement if (totalBubbles >= 1000) { await unlockAchievement(achievement1000Bubbles); } // 5000 bubbles achievement if (totalBubbles >= 5000) { await unlockAchievement(achievement5000Bubbles); } } /// Check zen mode achievements Future checkZenModeAchievements(double sessionTime) async { if (!_isEnabled) return; if (!_isSignedIn) return; // Zen master achievement (10 minutes in zen mode) if (sessionTime >= 600) { await unlockAchievement(achievementZenMaster); } } /// Check score-based achievements Future checkScoreAchievements(int score, double timeToReachScore) async { if (!_isEnabled) return; if (!_isSignedIn) return; // Speed demon achievement (reach 1000 points in under 2 minutes) if (score >= 1000 && timeToReachScore <= 120) { await unlockAchievement(achievementSpeedDemon); } } /// Submit various scores to leaderboards Future submitGameResults({ required int finalScore, required bool isZenMode, required int totalBubblesPopped, required double sessionLength, }) async { if (!_isEnabled) return; if (!_isSignedIn) return; // Submit to appropriate leaderboards if (isZenMode) { await submitScore(leaderboardZenMode, sessionLength.round()); } else { await submitScore(leaderboardHighScore, finalScore); } await submitScore(leaderboardTotalBubbles, totalBubblesPopped); await submitScore(leaderboardLongestSession, sessionLength.round()); // Check achievements await checkBubbleAchievements(totalBubblesPopped); if (isZenMode) { await checkZenModeAchievements(sessionLength); } else { await checkScoreAchievements(finalScore, sessionLength); } } }