// lib/features/gamification/providers/gamification_provider.dart

import 'package:flutter/foundation.dart';
import '../../../core/utils/error_utils.dart';
import '../models/gamification_models.dart';
import '../services/gamification_service.dart';

class GamificationProvider extends ChangeNotifier {
  final GamificationService _service = GamificationService();

  // State
  UserGamificationProfile? profile;
  List<LeaderboardEntry> leaderboard = [];
  List<ShopItem> shopItems = [];
  List<AchievementBadge> achievements = [];

  // Leaderboard filters — matches web version
  String leaderboardDistrict = 'Overall Kerala';
  String leaderboardTimePeriod = 'all_time'; // 'all_time' | 'this_month'

  bool isLoading = false;
  String? error;

  // ---------------------------------------------------------------------------
  // Load everything at once (called when ContributeScreen is mounted)
  // ---------------------------------------------------------------------------
  Future<void> loadAll() async {
    isLoading = true;
    error = null;
    notifyListeners();

    try {
      final results = await Future.wait([
        _service.getProfile(),
        _service.getLeaderboard(district: leaderboardDistrict, timePeriod: leaderboardTimePeriod),
        _service.getShopItems(),
        _service.getAchievements(),
      ]);

      profile    = results[0] as UserGamificationProfile;
      leaderboard = results[1] as List<LeaderboardEntry>;
      shopItems  = results[2] as List<ShopItem>;
      achievements = results[3] as List<AchievementBadge>;
    } catch (e) {
      error = userFriendlyError(e);
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }

  // ---------------------------------------------------------------------------
  // Change district filter
  // ---------------------------------------------------------------------------
  Future<void> setDistrict(String district) async {
    if (leaderboardDistrict == district) return;
    leaderboardDistrict = district;
    notifyListeners();
    try {
      leaderboard = await _service.getLeaderboard(district: district, timePeriod: leaderboardTimePeriod);
    } catch (e) {
      error = userFriendlyError(e);
    }
    notifyListeners();
  }

  // ---------------------------------------------------------------------------
  // Change time period filter
  // ---------------------------------------------------------------------------
  Future<void> setTimePeriod(String period) async {
    if (leaderboardTimePeriod == period) return;
    leaderboardTimePeriod = period;
    notifyListeners();
    try {
      leaderboard = await _service.getLeaderboard(district: leaderboardDistrict, timePeriod: period);
    } catch (e) {
      error = userFriendlyError(e);
    }
    notifyListeners();
  }

  // ---------------------------------------------------------------------------
  // Redeem a shop item — deducts RP locally optimistically, returns voucher code
  // ---------------------------------------------------------------------------
  Future<String> redeemItem(String itemId) async {
    final item = shopItems.firstWhere((s) => s.id == itemId);

    // Optimistically deduct RP
    if (profile != null) {
      profile = UserGamificationProfile(
        userId: profile!.userId,
        lifetimeEp: profile!.lifetimeEp,
        currentEp: profile!.currentEp,
        currentRp: profile!.currentRp - item.rpCost,
        tier: profile!.tier,
      );
      notifyListeners();
    }

    try {
      final record = await _service.redeemItem(itemId);
      return record.voucherCode;
    } catch (e) {
      // Rollback on failure
      if (profile != null) {
        profile = UserGamificationProfile(
          userId: profile!.userId,
          lifetimeEp: profile!.lifetimeEp,
          currentEp: profile!.currentEp,
          currentRp: profile!.currentRp + item.rpCost,
          tier: profile!.tier,
        );
        notifyListeners();
      }
      rethrow;
    }
  }

  // ---------------------------------------------------------------------------
  // Submit a contribution
  // ---------------------------------------------------------------------------
  Future<void> submitContribution(Map<String, dynamic> data) async {
    await _service.submitContribution(data);
  }
}
