// lib/features/gamification/services/gamification_service.dart
//
// Real API service for the Contributor / Gamification module.
// Calls the Node.js gamification server at app.eventifyplus.com.

import '../../../core/api/api_client.dart';
import '../../../core/api/api_endpoints.dart';
import '../../../core/storage/token_storage.dart';
import '../models/gamification_models.dart';

class GamificationService {
  final ApiClient _api = ApiClient();

  /// Helper: get current user's email for API calls.
  Future<String> _getUserEmail() async {
    final email = await TokenStorage.getUsername();
    return email ?? '';
  }

  // ---------------------------------------------------------------------------
  // Dashboard (profile + submissions)
  // GET /v1/gamification/dashboard?user_id={email}
  // ---------------------------------------------------------------------------
  Future<DashboardResponse> getDashboard() async {
    final email = await _getUserEmail();
    final url = '${ApiEndpoints.gamificationDashboard}?user_id=$email';
    final res = await _api.post(url, requiresAuth: false);

    final profileJson = res['profile'] as Map<String, dynamic>? ?? {};
    final rawSubs = res['submissions'] as List? ?? [];
    final rawAchievements = res['achievements'] as List? ?? [];

    final submissions = rawSubs
        .map((s) => SubmissionModel.fromJson(Map<String, dynamic>.from(s as Map)))
        .toList();

    final achievements = rawAchievements
        .map((a) => AchievementBadge.fromJson(Map<String, dynamic>.from(a as Map)))
        .toList();

    return DashboardResponse(
      profile: UserGamificationProfile.fromJson(profileJson),
      submissions: submissions,
      achievements: achievements,
    );
  }

  // ---------------------------------------------------------------------------
  // Public contributor profile (any user by userId / email)
  // GET /v1/gamification/dashboard?user_id={userId}
  // ---------------------------------------------------------------------------
  Future<DashboardResponse> getDashboardForUser(String userId) async {
    final url = '${ApiEndpoints.gamificationDashboard}?user_id=$userId';
    final res = await _api.post(url, requiresAuth: false);

    final profileJson = res['profile'] as Map<String, dynamic>? ?? {};
    final rawSubs = res['submissions'] as List? ?? [];
    final rawAchievements = res['achievements'] as List? ?? [];

    final submissions = rawSubs
        .map((s) => SubmissionModel.fromJson(Map<String, dynamic>.from(s as Map)))
        .toList();

    final achievements = rawAchievements
        .map((a) => AchievementBadge.fromJson(Map<String, dynamic>.from(a as Map)))
        .toList();

    return DashboardResponse(
      profile: UserGamificationProfile.fromJson(profileJson),
      submissions: submissions,
      achievements: achievements,
    );
  }

  /// Convenience — returns just the profile (backward-compatible with provider).
  Future<UserGamificationProfile> getProfile() async {
    final dashboard = await getDashboard();
    return dashboard.profile;
  }

  // ---------------------------------------------------------------------------
  // Leaderboard
  // GET /v1/gamification/leaderboard?period=all|month&district=X&user_id=Y&limit=50
  // ---------------------------------------------------------------------------
  Future<LeaderboardResponse> getLeaderboard({
    required String district,
    required String timePeriod,
  }) async {
    final email = await _getUserEmail();

    // Map Flutter filter values to API params
    final period = timePeriod == 'this_month' ? 'month' : 'all';

    final params = <String, String>{
      'period': period,
      'user_id': email,
      'limit': '50',
    };
    if (district != 'Overall Kerala') {
      params['district'] = district;
    }

    final query = Uri(queryParameters: params).query;
    final url = '${ApiEndpoints.leaderboard}?$query';
    final res = await _api.post(url, requiresAuth: false);

    final rawList = res['leaderboard'] as List? ?? [];
    final entries = rawList
        .map((e) => LeaderboardEntry.fromJson(Map<String, dynamic>.from(e as Map)))
        .toList();

    CurrentUserStats? currentUser;
    if (res['currentUser'] != null && res['currentUser'] is Map) {
      currentUser = CurrentUserStats.fromJson(
        Map<String, dynamic>.from(res['currentUser'] as Map),
      );
    }

    return LeaderboardResponse(
      entries: entries,
      currentUser: currentUser,
      totalParticipants: (res['totalParticipants'] as num?)?.toInt() ?? entries.length,
    );
  }

  // ---------------------------------------------------------------------------
  // Shop Items
  // GET /v1/shop/items
  // ---------------------------------------------------------------------------
  Future<List<ShopItem>> getShopItems() async {
    final res = await _api.post(ApiEndpoints.shopItems, requiresAuth: false);
    final rawItems = res['items'] as List? ?? [];
    return rawItems
        .map((e) => ShopItem.fromJson(Map<String, dynamic>.from(e as Map)))
        .toList();
  }

  // ---------------------------------------------------------------------------
  // Redeem Item
  // POST /v1/shop/redeem  body: { user_id, item_id }
  // ---------------------------------------------------------------------------
  Future<RedemptionRecord> redeemItem(String itemId) async {
    final email = await _getUserEmail();
    final res = await _api.post(
      ApiEndpoints.shopRedeem,
      body: {'user_id': email, 'item_id': itemId},
      requiresAuth: false,
    );
    final voucher = res['voucher'] as Map<String, dynamic>? ?? res;
    return RedemptionRecord.fromJson(Map<String, dynamic>.from(voucher));
  }

  // ---------------------------------------------------------------------------
  // Submit Contribution
  // POST /v1/gamification/submit-event  body: event data
  // ---------------------------------------------------------------------------
  Future<void> submitContribution(Map<String, dynamic> data) async {
    final email = await _getUserEmail();
    final body = <String, dynamic>{'user_id': email, ...data};
    await _api.post(
      ApiEndpoints.contributeSubmit,
      body: body,
      requiresAuth: false,
    );
  }

  // ---------------------------------------------------------------------------
  // Achievements — sourced from dashboard API `achievements` array.
  // Falls back to default badges if API doesn't return achievements yet.
  // ---------------------------------------------------------------------------
  Future<List<AchievementBadge>> getAchievements() async {
    try {
      final dashboard = await getDashboard();
      if (dashboard.achievements.isNotEmpty) return dashboard.achievements;
    } catch (_) {
      // Fall through to defaults
    }
    return _defaultBadges;
  }

  static const _defaultBadges = [
    AchievementBadge(id: 'badge-01', title: 'First Step',        description: 'Submit your first event.',        iconName: 'edit',          isUnlocked: false, progress: 0.0),
    AchievementBadge(id: 'badge-02', title: 'Silver Streak',     description: 'Submit 5 events.',               iconName: 'trending_up',   isUnlocked: false, progress: 0.0),
    AchievementBadge(id: 'badge-03', title: 'Gold Rush',         description: 'Submit 15 events.',              iconName: 'emoji_events',  isUnlocked: false, progress: 0.0),
    AchievementBadge(id: 'badge-04', title: 'Top 10',            description: 'Reach top 10 on leaderboard.',   iconName: 'leaderboard',   isUnlocked: false, progress: 0.0),
    AchievementBadge(id: 'badge-05', title: 'Image Pro',         description: 'Upload 10 event images.',        iconName: 'photo_library', isUnlocked: false, progress: 0.0),
    AchievementBadge(id: 'badge-06', title: 'Pioneer',           description: 'One of the first contributors.', iconName: 'rocket_launch', isUnlocked: false, progress: 0.0),
    AchievementBadge(id: 'badge-07', title: 'Community Star',    description: 'Get 10 events approved.',        iconName: 'verified',      isUnlocked: false, progress: 0.0),
    AchievementBadge(id: 'badge-08', title: 'Event Hunter',      description: 'Submit 25 events.',              iconName: 'event_hunter',  isUnlocked: false, progress: 0.0),
    AchievementBadge(id: 'badge-09', title: 'District Champion', description: 'Rank #1 in your district.',      iconName: 'location_on',   isUnlocked: false, progress: 0.0),
    AchievementBadge(id: 'badge-10', title: 'Platinum Achiever', description: 'Earn 1500 EP.',                  iconName: 'diamond',       isUnlocked: false, progress: 0.0),
    AchievementBadge(id: 'badge-11', title: 'Diamond Legend',    description: 'Earn 5000 EP.',                  iconName: 'workspace_premium', isUnlocked: false, progress: 0.0),
  ];
}
