// lib/features/gamification/services/gamification_service.dart // // Stub service using the real API contract from TechDocs v2. // All methods currently return mock data. // TODO: replace each mock block with a real ApiClient call once // the backend endpoints are live on uat.eventifyplus.com. import 'dart:math'; import '../models/gamification_models.dart'; class GamificationService { // --------------------------------------------------------------------------- // User Gamification Profile // TODO: replace with ApiClient.get(ApiEndpoints.gamificationProfile) // --------------------------------------------------------------------------- Future getProfile() async { await Future.delayed(const Duration(milliseconds: 400)); return const UserGamificationProfile( userId: 'mock-user-001', lifetimeEp: 320, currentEp: 70, currentRp: 45, tier: ContributorTier.SILVER, ); } // --------------------------------------------------------------------------- // Leaderboard // district: 'Overall Kerala' | 'Thiruvananthapuram' | 'Kollam' | ... // timePeriod: 'all_time' | 'this_month' // TODO: replace with ApiClient.get(ApiEndpoints.leaderboard, params: {'district': district, 'period': timePeriod}) // --------------------------------------------------------------------------- Future> getLeaderboard({ required String district, required String timePeriod, }) async { await Future.delayed(const Duration(milliseconds: 500)); // Realistic mock names per district final names = [ 'Annette Black', 'Jerome Bell', 'Theresa Webb', 'Courtney Henry', 'Cameron Williamson', 'Dianne Russell', 'Wade Warren', 'Albert Flores', 'Kristin Watson', 'Guy Hawkins', ]; final rng = Random(district.hashCode ^ timePeriod.hashCode); final baseEp = timePeriod == 'this_month' ? 800 : 4500; final entries = List.generate(10, (i) { final ep = baseEp - (i * (timePeriod == 'this_month' ? 55 : 280)) + rng.nextInt(30); return LeaderboardEntry( rank: i + 1, username: names[i], lifetimeEp: ep, tier: tierFromEp(ep), eventsCount: 149 - i * 12, isCurrentUser: i == 7, // mock: current user is rank 8 ); }); return entries; } // --------------------------------------------------------------------------- // Redeem Shop Items // TODO: replace with ApiClient.get(ApiEndpoints.shopItems) // --------------------------------------------------------------------------- Future> getShopItems() async { await Future.delayed(const Duration(milliseconds: 400)); return const [ ShopItem( id: 'item-001', name: 'Amazon ₹500 Voucher', description: 'Redeem for any purchase on Amazon India.', rpCost: 50, stockQuantity: 20, ), ShopItem( id: 'item-002', name: 'Swiggy ₹200 Voucher', description: 'Free food delivery credit on Swiggy.', rpCost: 20, stockQuantity: 35, ), ShopItem( id: 'item-003', name: 'Eventify Pro — 1 Month', description: 'Premium access to Eventify.Plus features.', rpCost: 30, stockQuantity: 100, ), ShopItem( id: 'item-004', name: 'Zomato ₹150 Voucher', description: 'Discount on your next Zomato order.', rpCost: 15, stockQuantity: 50, ), ShopItem( id: 'item-005', name: 'BookMyShow ₹300 Voucher', description: 'Movie & event ticket credit on BookMyShow.', rpCost: 30, stockQuantity: 15, ), ShopItem( id: 'item-006', name: 'Exclusive Badge', description: 'Rare "Pioneer" badge for your profile.', rpCost: 5, stockQuantity: 0, // out of stock ), ]; } // --------------------------------------------------------------------------- // Redeem an item // TODO: replace with ApiClient.post(ApiEndpoints.shopRedeem, body: {'item_id': itemId}) // --------------------------------------------------------------------------- Future redeemItem(String itemId) async { await Future.delayed(const Duration(milliseconds: 600)); // Generate a fake voucher code final code = 'EVT-${itemId.toUpperCase().replaceAll('-', '').substring(0, 4)}-${Random().nextInt(9000) + 1000}'; return RedemptionRecord( id: 'redemption-${DateTime.now().millisecondsSinceEpoch}', itemId: itemId, rpSpent: 0, // provider will look up cost voucherCode: code, timestamp: DateTime.now(), ); } // --------------------------------------------------------------------------- // Submit Contribution // TODO: replace with ApiClient.post(ApiEndpoints.contributeSubmit, body: data) // --------------------------------------------------------------------------- Future submitContribution(Map data) async { await Future.delayed(const Duration(milliseconds: 800)); // Mock always succeeds } // --------------------------------------------------------------------------- // Achievements // --------------------------------------------------------------------------- Future> getAchievements() async { await Future.delayed(const Duration(milliseconds: 300)); return const [ AchievementBadge( id: 'badge-01', title: 'First Submission', description: 'Submitted your first event.', iconName: 'edit', isUnlocked: true, progress: 1.0, ), AchievementBadge( id: 'badge-02', title: 'Silver Streak', description: 'Reached Silver tier.', iconName: 'star', isUnlocked: true, progress: 1.0, ), AchievementBadge( id: 'badge-03', title: 'Gold Rush', description: 'Reach Gold tier (500 EP).', iconName: 'emoji_events', isUnlocked: false, progress: 0.64, ), AchievementBadge( id: 'badge-04', title: 'Top 10', description: 'Appear in the district leaderboard top 10.', iconName: 'leaderboard', isUnlocked: false, progress: 0.5, ), AchievementBadge( id: 'badge-05', title: 'Image Pro', description: 'Submit 10 events with 3+ images.', iconName: 'photo_library', isUnlocked: false, progress: 0.3, ), AchievementBadge( id: 'badge-06', title: 'Pioneer', description: 'One of the first 100 contributors.', iconName: 'verified', isUnlocked: true, progress: 1.0, ), ]; } }