import 'package:em2rp/services/api_service.dart'; /// Service générique pour les opérations de lecture de données via Cloud Functions class DataService { final ApiService _apiService; DataService(this._apiService); /// Récupère toutes les options Future>> getOptions() async { try { final result = await _apiService.call('getOptions', {}); final options = result['options'] as List?; if (options == null) return []; return options.map((e) => e as Map).toList(); } catch (e) { throw Exception('Erreur lors de la récupération des options: $e'); } } /// Récupère tous les types d'événements Future>> getEventTypes() async { try { final result = await _apiService.call('getEventTypes', {}); final eventTypes = result['eventTypes'] as List?; if (eventTypes == null) return []; return eventTypes.map((e) => e as Map).toList(); } catch (e) { throw Exception('Erreur lors de la récupération des types d\'événements: $e'); } } /// Récupère tous les rôles Future>> getRoles() async { try { final result = await _apiService.call('getRoles', {}); final roles = result['roles'] as List?; if (roles == null) return []; return roles.map((e) => e as Map).toList(); } catch (e) { throw Exception('Erreur lors de la récupération des rôles: $e'); } } /// Met à jour les équipements d'un événement Future updateEventEquipment({ required String eventId, List>? assignedEquipment, String? preparationStatus, String? loadingStatus, String? unloadingStatus, String? returnStatus, }) async { try { final data = {'eventId': eventId}; if (assignedEquipment != null) data['assignedEquipment'] = assignedEquipment; if (preparationStatus != null) data['preparationStatus'] = preparationStatus; if (loadingStatus != null) data['loadingStatus'] = loadingStatus; if (unloadingStatus != null) data['unloadingStatus'] = unloadingStatus; if (returnStatus != null) data['returnStatus'] = returnStatus; await _apiService.call('updateEventEquipment', data); } catch (e) { throw Exception('Erreur lors de la mise à jour des équipements de l\'événement: $e'); } } /// Met à jour uniquement le statut d'un équipement Future updateEquipmentStatusOnly({ required String equipmentId, String? status, int? availableQuantity, }) async { try { final data = {'equipmentId': equipmentId}; if (status != null) data['status'] = status; if (availableQuantity != null) data['availableQuantity'] = availableQuantity; await _apiService.call('updateEquipmentStatusOnly', data); } catch (e) { throw Exception('Erreur lors de la mise à jour du statut de l\'équipement: $e'); } } /// Met à jour un événement Future updateEvent(String eventId, Map data) async { try { final requestData = {'eventId': eventId, 'data': data}; await _apiService.call('updateEvent', requestData); } catch (e) { throw Exception('Erreur lors de la mise à jour de l\'événement: $e'); } } /// Supprime un événement Future deleteEvent(String eventId) async { try { await _apiService.call('deleteEvent', {'eventId': eventId}); } catch (e) { throw Exception('Erreur lors de la suppression de l\'événement: $e'); } } /// Crée un nouvel équipement Future createEquipment(String equipmentId, Map data) async { try { final requestData = {'equipmentId': equipmentId, ...data}; await _apiService.call('createEquipment', requestData); } catch (e) { throw Exception('Erreur lors de la création de l\'équipement: $e'); } } /// Met à jour un équipement Future updateEquipment(String equipmentId, Map data) async { try { final requestData = {'equipmentId': equipmentId, ...data}; await _apiService.call('updateEquipment', requestData); } catch (e) { throw Exception('Erreur lors de la mise à jour de l\'équipement: $e'); } } /// Supprime un équipement Future deleteEquipment(String equipmentId) async { try { await _apiService.call('deleteEquipment', {'equipmentId': equipmentId}); } catch (e) { throw Exception('Erreur lors de la suppression de l\'équipement: $e'); } } /// Récupère les événements utilisant un type d'événement donné Future>> getEventsByEventType(String eventTypeId) async { try { final result = await _apiService.call('getEventsByEventType', {'eventTypeId': eventTypeId}); final events = result['events'] as List?; if (events == null) return []; return events.map((e) => e as Map).toList(); } catch (e) { throw Exception('Erreur lors de la récupération des événements: $e'); } } /// Crée un type d'événement Future createEventType({ required String name, required double defaultPrice, }) async { try { final result = await _apiService.call('createEventType', { 'name': name, 'defaultPrice': defaultPrice, }); return result['id'] as String; } catch (e) { throw Exception('Erreur lors de la création du type d\'événement: $e'); } } /// Met à jour un type d'événement Future updateEventType({ required String eventTypeId, String? name, double? defaultPrice, }) async { try { final data = {'eventTypeId': eventTypeId}; if (name != null) data['name'] = name; if (defaultPrice != null) data['defaultPrice'] = defaultPrice; await _apiService.call('updateEventType', data); } catch (e) { throw Exception('Erreur lors de la mise à jour du type d\'événement: $e'); } } /// Supprime un type d'événement Future deleteEventType(String eventTypeId) async { try { await _apiService.call('deleteEventType', {'eventTypeId': eventTypeId}); } catch (e) { throw Exception('Erreur lors de la suppression du type d\'événement: $e'); } } /// Crée une option Future createOption(String code, Map data) async { try { final requestData = {'code': code, ...data}; final result = await _apiService.call('createOption', requestData); return result['id'] as String? ?? code; } catch (e) { throw Exception('Erreur lors de la création de l\'option: $e'); } } /// Met à jour une option Future updateOption(String optionId, Map data) async { try { final requestData = {'optionId': optionId, ...data}; await _apiService.call('updateOption', requestData); } catch (e) { throw Exception('Erreur lors de la mise à jour de l\'option: $e'); } } /// Supprime une option Future deleteOption(String optionId) async { try { await _apiService.call('deleteOption', {'optionId': optionId}); } catch (e) { throw Exception('Erreur lors de la suppression de l\'option: $e'); } } // ============================================================================ // LECTURE DES DONNÉES (avec permissions côté serveur) // ============================================================================ /// Récupère tous les événements (filtrés selon permissions) /// Retourne { events: List, users: Map } Future> getEvents({String? userId}) async { try { final data = {}; if (userId != null) data['userId'] = userId; final result = await _apiService.call('getEvents', data); // Extraire events et users final events = result['events'] as List? ?? []; final users = result['users'] as Map? ?? {}; return { 'events': events.map((e) => e as Map).toList(), 'users': users, }; } catch (e) { throw Exception('Erreur lors de la récupération des événements: $e'); } } /// Récupère tous les équipements (avec masquage des prix selon permissions) Future>> getEquipments() async { try { print('[DataService] Calling getEquipments API...'); final result = await _apiService.call('getEquipments', {}); print('[DataService] API call successful, parsing result...'); final equipments = result['equipments'] as List?; if (equipments == null) { print('[DataService] No equipments in result'); return []; } print('[DataService] Found ${equipments.length} equipments'); return equipments.map((e) => e as Map).toList(); } catch (e) { print('[DataService] Error getting equipments: $e'); throw Exception('Erreur lors de la récupération des équipements: $e'); } } /// Récupère plusieurs équipements par leurs IDs Future>> getEquipmentsByIds(List equipmentIds) async { try { if (equipmentIds.isEmpty) return []; print('[DataService] Getting equipments by IDs: ${equipmentIds.length} items'); final result = await _apiService.call('getEquipmentsByIds', { 'equipmentIds': equipmentIds, }); final equipments = result['equipments'] as List?; if (equipments == null) { print('[DataService] No equipments in result'); return []; } print('[DataService] Found ${equipments.length} equipments by IDs'); return equipments.map((e) => e as Map).toList(); } catch (e) { print('[DataService] Error getting equipments by IDs: $e'); throw Exception('Erreur lors de la récupération des équipements: $e'); } } /// Récupère tous les conteneurs Future>> getContainers() async { try { final result = await _apiService.call('getContainers', {}); final containers = result['containers'] as List?; if (containers == null) return []; return containers.map((e) => e as Map).toList(); } catch (e) { throw Exception('Erreur lors de la récupération des conteneurs: $e'); } } /// Récupère plusieurs conteneurs par leurs IDs Future>> getContainersByIds(List containerIds) async { try { if (containerIds.isEmpty) return []; print('[DataService] Getting containers by IDs: ${containerIds.length} items'); final result = await _apiService.call('getContainersByIds', { 'containerIds': containerIds, }); final containers = result['containers'] as List?; if (containers == null) { print('[DataService] No containers in result'); return []; } print('[DataService] Found ${containers.length} containers by IDs'); return containers.map((e) => e as Map).toList(); } catch (e) { print('[DataService] Error getting containers by IDs: $e'); throw Exception('Erreur lors de la récupération des conteneurs: $e'); } } /// Récupère les maintenances (optionnellement filtrées par équipement) Future>> getMaintenances({String? equipmentId}) async { try { final data = {}; if (equipmentId != null) data['equipmentId'] = equipmentId; final result = await _apiService.call('getMaintenances', data); final maintenances = result['maintenances'] as List?; if (maintenances == null) return []; return maintenances.map((e) => e as Map).toList(); } catch (e) { throw Exception('Erreur lors de la récupération des maintenances: $e'); } } /// Récupère les containers contenant un équipement spécifique Future>> getContainersByEquipment(String equipmentId) async { try { final result = await _apiService.call('getContainersByEquipment', { 'equipmentId': equipmentId, }); final containers = result['containers'] as List?; if (containers == null) return []; return containers.map((e) => e as Map).toList(); } catch (e) { throw Exception('Erreur lors de la récupération des containers pour l\'équipement: $e'); } } // ============================================================================ // USER - Current User // ============================================================================ /// Récupère l'utilisateur actuellement authentifié avec son rôle Future> getCurrentUser() async { try { print('[DataService] Calling getCurrentUser API...'); final result = await _apiService.call('getCurrentUser', {}); print('[DataService] Current user loaded successfully'); return result['user'] as Map; } catch (e) { print('[DataService] Error getting current user: $e'); throw Exception('Erreur lors de la récupération de l\'utilisateur actuel: $e'); } } // ============================================================================ // ALERTS // ============================================================================ /// Récupère toutes les alertes Future>> getAlerts() async { try { final result = await _apiService.call('getAlerts', {}); final alerts = result['alerts'] as List?; if (alerts == null) return []; return alerts.map((e) => e as Map).toList(); } catch (e) { throw Exception('Erreur lors de la récupération des alertes: $e'); } } /// Marque une alerte comme lue Future markAlertAsRead(String alertId) async { try { await _apiService.call('markAlertAsRead', {'alertId': alertId}); } catch (e) { throw Exception('Erreur lors du marquage de l\'alerte comme lue: $e'); } } /// Supprime une alerte Future deleteAlert(String alertId) async { try { await _apiService.call('deleteAlert', {'alertId': alertId}); } catch (e) { throw Exception('Erreur lors de la suppression de l\'alerte: $e'); } } // ============================================================================ // EQUIPMENT AVAILABILITY // ============================================================================ /// Vérifie la disponibilité d'un équipement Future> checkEquipmentAvailability({ required String equipmentId, required DateTime startDate, required DateTime endDate, String? excludeEventId, }) async { try { final result = await _apiService.call('checkEquipmentAvailability', { 'equipmentId': equipmentId, 'startDate': startDate.toIso8601String(), 'endDate': endDate.toIso8601String(), if (excludeEventId != null) 'excludeEventId': excludeEventId, }); return result; } catch (e) { throw Exception('Erreur lors de la vérification de disponibilité: $e'); } } /// Récupère tous les IDs d'équipements et conteneurs en conflit pour une période /// Optimisé : une seule requête au lieu d'une par équipement Future> getConflictingEquipmentIds({ required DateTime startDate, required DateTime endDate, String? excludeEventId, int installationTime = 0, int disassemblyTime = 0, }) async { try { final result = await _apiService.call('getConflictingEquipmentIds', { 'startDate': startDate.toIso8601String(), 'endDate': endDate.toIso8601String(), if (excludeEventId != null) 'excludeEventId': excludeEventId, 'installationTime': installationTime, 'disassemblyTime': disassemblyTime, }); return result; } catch (e) { throw Exception('Erreur lors de la récupération des équipements en conflit: $e'); } } // ============================================================================ // MAINTENANCES // ============================================================================ /// Supprime une maintenance Future deleteMaintenance(String maintenanceId) async { try { await _apiService.call('deleteMaintenance', {'maintenanceId': maintenanceId}); } catch (e) { throw Exception('Erreur lors de la suppression de la maintenance: $e'); } } // ============================================================================ // USERS // ============================================================================ /// Récupère tous les utilisateurs (selon permissions) Future>> getUsers() async { try { final result = await _apiService.call('getUsers', {}); final users = result['users'] as List?; if (users == null) return []; return users.map((e) => e as Map).toList(); } catch (e) { throw Exception('Erreur lors de la récupération des utilisateurs: $e'); } } /// Récupère un utilisateur spécifique Future> getUser(String userId) async { try { final result = await _apiService.call('getUser', {'userId': userId}); return result['user'] as Map; } catch (e) { throw Exception('Erreur lors de la récupération de l\'utilisateur: $e'); } } /// Supprime un utilisateur (Auth + Firestore) Future deleteUser(String userId) async { try { await _apiService.call('deleteUser', {'userId': userId}); } catch (e) { throw Exception('Erreur lors de la suppression de l\'utilisateur: $e'); } } /// Met à jour un utilisateur Future updateUser(String userId, Map data) async { try { final requestData = {'userId': userId, ...data}; await _apiService.call('updateUser', requestData); } catch (e) { throw Exception('Erreur lors de la mise à jour de l\'utilisateur: $e'); } } }