import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:em2rp/models/event_model.dart'; import 'package:em2rp/services/data_service.dart'; import 'package:em2rp/services/api_service.dart'; import 'package:em2rp/utils/performance_monitor.dart'; class EventProvider with ChangeNotifier { final DataService _dataService = DataService(FirebaseFunctionsApiService()); List _events = []; bool _isLoading = false; List get events => _events; bool get isLoading => _isLoading; // Cache des utilisateurs chargés depuis getEvents Map> _usersCache = {}; // Cache pour éviter les rechargements inutiles DateTime? _lastLoadTime; String? _lastUserId; bool _lastCanViewAll = false; /// Vérifie si les données doivent être rechargées (cache de 30 secondes) bool _shouldReload(String userId, bool canViewAllEvents) { if (_lastLoadTime == null) return true; if (_lastUserId != userId || _lastCanViewAll != canViewAllEvents) return true; final now = DateTime.now(); final difference = now.difference(_lastLoadTime!); return difference.inSeconds > 30; } /// Charger les événements d'un utilisateur via l'API Future loadUserEvents(String userId, {bool canViewAllEvents = false, bool forceReload = false}) async { PerformanceMonitor.start('EventProvider.loadUserEvents'); // Éviter les rechargements inutiles if (!forceReload && !_shouldReload(userId, canViewAllEvents)) { print('Using cached events (loaded ${DateTime.now().difference(_lastLoadTime!).inSeconds}s ago)'); PerformanceMonitor.end('EventProvider.loadUserEvents'); return; } _isLoading = true; notifyListeners(); try { print('Loading events for user: $userId (canViewAllEvents: $canViewAllEvents)'); PerformanceMonitor.start('EventProvider.getEvents_API'); // Charger via l'API - les permissions sont vérifiées côté serveur final result = await _dataService.getEvents(userId: userId); PerformanceMonitor.end('EventProvider.getEvents_API'); final eventsData = result['events'] as List>; final usersData = result['users'] as Map; // Stocker les utilisateurs dans le cache _usersCache = usersData.map((key, value) => MapEntry(key, value as Map) ); print('Found ${eventsData.length} events from API'); PerformanceMonitor.start('EventProvider.parseEvents'); List allEvents = []; int failedCount = 0; // Parser chaque événement for (var eventData in eventsData) { try { final event = EventModel.fromMap(eventData, eventData['id'] as String); allEvents.add(event); } catch (e) { print('Failed to parse event ${eventData['id']}: $e'); failedCount++; } } PerformanceMonitor.end('EventProvider.parseEvents'); _events = allEvents; _lastLoadTime = DateTime.now(); _lastUserId = userId; _lastCanViewAll = canViewAllEvents; print('Successfully loaded ${_events.length} events (${failedCount} failed)'); _isLoading = false; notifyListeners(); PerformanceMonitor.end('EventProvider.loadUserEvents'); } catch (e) { print('Error loading events: $e'); _isLoading = false; notifyListeners(); PerformanceMonitor.end('EventProvider.loadUserEvents'); rethrow; } } /// Recharger les événements (utilise le dernier userId) Future refreshEvents(String userId, {bool canViewAllEvents = false}) async { await loadUserEvents(userId, canViewAllEvents: canViewAllEvents, forceReload: true); } /// Récupérer un événement spécifique par ID EventModel? getEventById(String eventId) { try { return _events.firstWhere((event) => event.id == eventId); } catch (e) { return null; } } /// Ajouter un nouvel événement Future addEvent(EventModel event) async { try { // L'événement est créé via l'API dans le service await refreshEvents(_lastUserId ?? '', canViewAllEvents: _lastCanViewAll); } catch (e) { print('Error adding event: $e'); rethrow; } } /// Mettre à jour un événement Future updateEvent(EventModel event) async { try { // Mise à jour locale immédiate final index = _events.indexWhere((e) => e.id == event.id); if (index != -1) { _events[index] = event; notifyListeners(); } } catch (e) { print('Error updating event: $e'); rethrow; } } /// Supprimer un événement Future deleteEvent(String eventId) async { try { await _dataService.deleteEvent(eventId); _events.removeWhere((event) => event.id == eventId); notifyListeners(); } catch (e) { print('Error deleting event: $e'); rethrow; } } /// Récupérer les données d'un utilisateur depuis le cache Map? getUserFromCache(String uid) { return _usersCache[uid]; } /// Récupérer les utilisateurs de la workforce d'un événement List> getWorkforceUsers(EventModel event) { final users = >[]; for (final dynamic userRef in event.workforce) { try { String? uid; // Tenter d'extraire l'UID if (userRef is String) { uid = userRef; } else { // Essayer d'extraire l'ID si c'est une DocumentReference final ref = userRef as DocumentReference?; uid = ref?.id; } if (uid != null) { final userData = getUserFromCache(uid); if (userData != null) { users.add(userData); } } } catch (e) { // Ignorer les références invalides print('Skipping invalid workforce reference: $userRef'); } } return users; } /// Vider la liste des événements void clearEvents() { _events = []; _lastLoadTime = null; _lastUserId = null; _lastCanViewAll = false; notifyListeners(); } }