// 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=${Uri.encodeComponent(email)}';
    final res = await _api.get(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=${Uri.encodeComponent(userId)}';
    final res = await _api.get(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.get(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.get(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: 'Newcomer',   description: 'First Event Posted',                 iconName: 'star',      isUnlocked: false, progress: 0.0),
    AchievementBadge(id: 'badge-02', title: 'Contributor', description: '10th Event Posted within a month',   iconName: 'crown',     isUnlocked: false, progress: 0.0),
    AchievementBadge(id: 'badge-03', title: 'On Fire!',    description: '3 Day Streak of logging in',       iconName: 'fire',      isUnlocked: false, progress: 0.67),
    AchievementBadge(id: 'badge-04', title: 'Verified',    description: 'Identity Verified successfully',    iconName: 'verified',  isUnlocked: true,  progress: 1.0),
    AchievementBadge(id: 'badge-05', title: 'Quality',     description: '5 Star Event Rating received',      iconName: 'star',      isUnlocked: false, progress: 0.0),
    AchievementBadge(id: 'badge-06', title: 'Community',   description: 'Referred 5 Friends to the platform', iconName: 'community', isUnlocked: false, progress: 0.4),
    AchievementBadge(id: 'badge-07', title: 'Expert',      description: 'Level 10 Reached in 3 months',       iconName: 'expert',    isUnlocked: false, progress: 0.0),
    AchievementBadge(id: 'badge-08', title: 'Precision',   description: '100% Data Accuracy on all events',   iconName: 'precision', isUnlocked: false, progress: 0.0),
  ];
}
