import 'package:em2rp/services/api_service.dart';
import 'package:em2rp/utils/debug_log.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<List<Map<String, dynamic>>> getOptions() async {
    try {
      final result = await _apiService.call('getOptions', {});
      final options = result['options'] as List<dynamic>?;
      if (options == null) return [];
      return options.map((e) => e as Map<String, dynamic>).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<List<Map<String, dynamic>>> getEventTypes() async {
    try {
      final result = await _apiService.call('getEventTypes', {});
      final eventTypes = result['eventTypes'] as List<dynamic>?;
      if (eventTypes == null) return [];
      return eventTypes.map((e) => e as Map<String, dynamic>).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<List<Map<String, dynamic>>> getRoles() async {
    try {
      final result = await _apiService.call('getRoles', {});
      final roles = result['roles'] as List<dynamic>?;
      if (roles == null) return [];
      return roles.map((e) => e as Map<String, dynamic>).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<void> updateEventEquipment({
    required String eventId,
    List<Map<String, dynamic>>? assignedEquipment,
    String? preparationStatus,
    String? loadingStatus,
    String? unloadingStatus,
    String? returnStatus,
  }) async {
    try {
      final data = <String, dynamic>{'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<void> updateEquipmentStatusOnly({
    required String equipmentId,
    String? status,
    int? availableQuantity,
  }) async {
    try {
      final data = <String, dynamic>{'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<void> updateEvent(String eventId, Map<String, dynamic> data) async {
    try {
      // Correction : fusionner eventId et les champs de data à la racine
      final requestData = {'eventId': eventId, ...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<void> 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 équipement
  Future<void> createEquipment(
      String equipmentId, Map<String, dynamic> data) async {
    try {
      // S'assurer que l'ID est dans les données
      final equipmentData = Map<String, dynamic>.from(data);
      equipmentData['id'] = equipmentId;

      await _apiService.call('createEquipment', equipmentData);
    } catch (e) {
      throw Exception('Erreur lors de la création de l\'équipement: $e');
    }
  }

  /// Met à jour un équipement
  Future<void> updateEquipment(
      String equipmentId, Map<String, dynamic> data) async {
    try {
      await _apiService.call('updateEquipment', {
        'equipmentId': equipmentId,
        'data': data,
      });
    } catch (e) {
      throw Exception('Erreur lors de la mise à jour de l\'équipement: $e');
    }
  }

  /// Supprime un équipement
  Future<void> deleteEquipment(String equipmentId,
      {bool forceDelete = false}) async {
    try {
      await _apiService.call('deleteEquipment', {
        'equipmentId': equipmentId,
        'forceDelete': forceDelete,
      });
    } on ApiException {
      rethrow;
    } 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<List<Map<String, dynamic>>> getEventsByEventType(
      String eventTypeId) async {
    try {
      final result = await _apiService
          .call('getEventsByEventType', {'eventTypeId': eventTypeId});
      final events = result['events'] as List<dynamic>?;
      if (events == null) return [];
      return events.map((e) => e as Map<String, dynamic>).toList();
    } catch (e) {
      throw Exception('Erreur lors de la récupération des événements: $e');
    }
  }

  /// Crée un type d'événement
  Future<String> 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<void> updateEventType({
    required String eventTypeId,
    String? name,
    double? defaultPrice,
  }) async {
    try {
      final data = <String, dynamic>{'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<void> 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<String> createOption(String code, Map<String, dynamic> data) async {
    try {
      final requestData = {
        'id': code, // Ajouter l'ID en utilisant le code comme identifiant
        '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<void> updateOption(String optionId, Map<String, dynamic> data) async {
    try {
      final requestData = {'optionId': optionId, 'data': data};
      await _apiService.call('updateOption', requestData);
    } catch (e) {
      throw Exception('Erreur lors de la mise à jour de l\'option: $e');
    }
  }

  /// Supprime une option
  Future<void> 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<Map>, users: Map<String, Map> }
  Future<Map<String, dynamic>> getEvents({String? userId}) async {
    try {
      final data = <String, dynamic>{};
      if (userId != null) data['userId'] = userId;

      final result = await _apiService.call('getEvents', data);

      // Extraire events et users
      final events = result['events'] as List<dynamic>? ?? [];
      final users = result['users'] as Map<String, dynamic>? ?? {};

      return {
        'events': events.map((e) => e as Map<String, dynamic>).toList(),
        'users': users,
      };
    } catch (e) {
      throw Exception('Erreur lors de la récupération des événements: $e');
    }
  }

  /// Récupère les événements d'un mois spécifique (lazy loading optimisé)
  Future<Map<String, dynamic>> getEventsByMonth({
    required String userId,
    required int year,
    required int month,
  }) async {
    try {
      print('[DataService] Calling getEventsByMonth for $year-$month');
      final result = await _apiService.call('getEventsByMonth', {
        'userId': userId,
        'year': year,
        'month': month,
      });

      // Extraire events et users
      final events = result['events'] as List<dynamic>? ?? [];
      final users = result['users'] as Map<String, dynamic>? ?? {};

      print(
          '[DataService] Events loaded for $year-$month: ${events.length} events');

      return {
        'events': events.map((e) => e as Map<String, dynamic>).toList(),
        'users': users,
      };
    } catch (e) {
      print('[DataService] Error getting events by month: $e');
      throw Exception(
          'Erreur lors de la récupération des événements du mois: $e');
    }
  }

  /// Recherche des événements accessibles à l'utilisateur.
  Future<List<Map<String, dynamic>>> searchEvents({
    required String userId,
    required String query,
    int limit = 20,
  }) async {
    try {
      final result = await _apiService.call('searchEvents', {
        'userId': userId,
        'query': query,
        'limit': limit,
      });

      final events = result['events'] as List<dynamic>?;
      if (events == null) {
        return [];
      }

      return events.map((e) => e as Map<String, dynamic>).toList();
    } catch (e) {
      throw Exception('Erreur lors de la recherche d\'événements: $e');
    }
  }

  /// Récupère un événement avec tous les détails (équipements complets + containers avec enfants)
  Future<Map<String, dynamic>> getEventWithDetails(String eventId) async {
    try {
      print('[DataService] Getting event with details: $eventId');
      final result = await _apiService.call('getEventWithDetails', {
        'eventId': eventId,
      });

      final event = result['event'] as Map<String, dynamic>?;
      final equipments = result['equipments'] as Map<String, dynamic>? ?? {};
      final containers = result['containers'] as Map<String, dynamic>? ?? {};

      if (event == null) {
        throw Exception('Event not found');
      }

      print(
          '[DataService] Event loaded with ${equipments.length} equipments and ${containers.length} containers');

      return {
        'event': event,
        'equipments': equipments,
        'containers': containers,
      };
    } catch (e) {
      print('[DataService] Error getting event with details: $e');
      throw Exception(
          'Erreur lors de la récupération de l\'événement avec détails: $e');
    }
  }

  /// Récupère tous les équipements (avec masquage des prix selon permissions)
  Future<List<Map<String, dynamic>>> 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<dynamic>?;
      if (equipments == null) {
        print('[DataService] No equipments in result');
        return [];
      }
      print('[DataService] Found ${equipments.length} equipments');
      return equipments.map((e) => e as Map<String, dynamic>).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<List<Map<String, dynamic>>> getEquipmentsByIds(
      List<String> 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<dynamic>?;
      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<String, dynamic>).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<List<Map<String, dynamic>>> getContainers() async {
    try {
      final result = await _apiService.call('getContainers', {});
      final containers = result['containers'] as List<dynamic>?;
      if (containers == null) return [];
      return containers.map((e) => e as Map<String, dynamic>).toList();
    } catch (e) {
      throw Exception('Erreur lors de la récupération des conteneurs: $e');
    }
  }

  /// Récupère plusieurs containers par leurs IDs
  Future<List<Map<String, dynamic>>> getContainersByIds(
      List<String> 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<dynamic>?;
      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<String, dynamic>).toList();
    } catch (e) {
      print('[DataService] Error getting containers by IDs: $e');
      throw Exception('Erreur lors de la récupération des containers: $e');
    }
  }

  // ============================================================================
  // EQUIPMENTS & CONTAINERS - Pagination
  // ============================================================================

  /// Récupère les équipements avec pagination et filtrage
  Future<Map<String, dynamic>> getEquipmentsPaginated({
    int limit = 20,
    String? startAfter,
    String? category,
    String? status,
    String? searchQuery,
    String sortBy = 'id',
    String sortOrder = 'asc',
  }) async {
    try {
      final params = <String, dynamic>{
        'limit': limit,
        'sortBy': sortBy,
        'sortOrder': sortOrder,
      };

      if (startAfter != null) params['startAfter'] = startAfter;
      if (category != null) params['category'] = category;
      if (status != null) params['status'] = status;
      if (searchQuery != null && searchQuery.isNotEmpty) {
        params['searchQuery'] = searchQuery;
      }

      final result =
          await (_apiService as FirebaseFunctionsApiService).callPaginated(
        'getEquipmentsPaginated',
        params,
      );

      return {
        'equipments': (result['equipments'] as List<dynamic>?)
                ?.map((e) => e as Map<String, dynamic>)
                .toList() ??
            [],
        'hasMore': result['hasMore'] as bool? ?? false,
        'lastVisible': result['lastVisible'] as String?,
        'total': result['total'] as int? ?? 0,
      };
    } catch (e) {
      DebugLog.error('[DataService] Error in getEquipmentsPaginated', e);
      throw Exception(
          'Erreur lors de la récupération paginée des équipements: $e');
    }
  }

  /// Récupère les containers avec pagination et filtrage
  Future<Map<String, dynamic>> getContainersPaginated({
    int limit = 20,
    String? startAfter,
    String? type,
    String? status,
    String? searchQuery,
    String? category,
    String sortBy = 'id',
    String sortOrder = 'asc',
  }) async {
    try {
      final params = <String, dynamic>{
        'limit': limit,
        'sortBy': sortBy,
        'sortOrder': sortOrder,
      };

      if (startAfter != null) params['startAfter'] = startAfter;
      if (type != null) params['type'] = type;
      if (status != null) params['status'] = status;
      if (category != null) params['category'] = category;
      if (searchQuery != null && searchQuery.isNotEmpty) {
        params['searchQuery'] = searchQuery;
      }

      final result =
          await (_apiService as FirebaseFunctionsApiService).callPaginated(
        'getContainersPaginated',
        params,
      );

      return {
        'containers': (result['containers'] as List<dynamic>?)
                ?.map((e) => e as Map<String, dynamic>)
                .toList() ??
            [],
        'hasMore': result['hasMore'] as bool? ?? false,
        'lastVisible': result['lastVisible'] as String?,
        'total': result['total'] as int? ?? 0,
      };
    } catch (e) {
      DebugLog.error('[DataService] Error in getContainersPaginated', e);
      throw Exception(
          'Erreur lors de la récupération paginée des containers: $e');
    }
  }

  /// Recherche rapide (autocomplétion)
  Future<List<Map<String, dynamic>>> quickSearch(
    String query, {
    int limit = 10,
    bool includeEquipments = true,
    bool includeContainers = true,
  }) async {
    try {
      return await (_apiService as FirebaseFunctionsApiService).quickSearch(
        query,
        limit: limit,
        includeEquipments: includeEquipments,
        includeContainers: includeContainers,
      );
    } catch (e) {
      DebugLog.error('[DataService] Error in quickSearch', e);
      return [];
    }
  }

  /// Recherche des équipements pour l'assistant IA avec fallback paginé.
  Future<List<Map<String, dynamic>>> searchEquipmentsForAssistant({
    required String query,
    int limit = 12,
  }) async {
    final normalizedQuery = query.trim();
    if (normalizedQuery.isEmpty) {
      return [];
    }

    try {
      final quickResults = await quickSearch(
        normalizedQuery,
        limit: limit,
        includeEquipments: true,
        includeContainers: false,
      );

      final equipmentResults = quickResults
          .where((item) =>
              (item['type']?.toString().toLowerCase() ?? '') == 'equipment')
          .map(_normalizeAssistantEquipment)
          .toList();

      if (equipmentResults.isNotEmpty) {
        return equipmentResults;
      }

      final paginated = await getEquipmentsPaginated(
        limit: limit,
        searchQuery: normalizedQuery,
        sortBy: 'id',
        sortOrder: 'asc',
      );

      final equipments =
          paginated['equipments'] as List<Map<String, dynamic>>? ?? [];
      return equipments.map(_normalizeAssistantEquipment).toList();
    } catch (e) {
      DebugLog.error('[DataService] Error in searchEquipmentsForAssistant', e);
      throw Exception('Erreur lors de la recherche de matériel: $e');
    }
  }

  /// Vérifie la disponibilité d'un équipement dans un format normalisé pour l'IA.
  Future<Map<String, dynamic>> checkEquipmentAvailabilityForAssistant({
    required String equipmentId,
    required DateTime startDate,
    required DateTime endDate,
    String? excludeEventId,
  }) async {
    try {
      final result = await checkEquipmentAvailability(
        equipmentId: equipmentId,
        startDate: startDate,
        endDate: endDate,
        excludeEventId: excludeEventId,
      );

      final available = result['available'] as bool? ?? true;
      final conflicts = (result['conflicts'] as List<dynamic>? ?? const [])
          .whereType<Map<String, dynamic>>()
          .map((conflict) {
        final eventData =
            conflict['eventData'] as Map<String, dynamic>? ?? const {};
        final eventName =
            (eventData['Name'] ?? conflict['eventName'] ?? '').toString();
        return {
          'eventId': conflict['eventId']?.toString() ?? '',
          'eventName': eventName,
          'overlapDays': conflict['overlapDays'] as int? ?? 0,
        };
      }).toList();

      return {
        'equipmentId': equipmentId,
        'available': available,
        'conflictCount': conflicts.length,
        'conflicts': conflicts,
      };
    } catch (e) {
      DebugLog.error(
          '[DataService] Error in checkEquipmentAvailabilityForAssistant', e);
      throw Exception('Erreur lors de la vérification de disponibilité: $e');
    }
  }

  /// Retourne des événements passés, idéalement filtrés par type d'événement.
  Future<List<Map<String, dynamic>>> getPastEventsForAssistant({
    String? eventTypeId,
    int limit = 10,
  }) async {
    try {
      final now = DateTime.now();
      final events = eventTypeId != null && eventTypeId.isNotEmpty
          ? await getEventsByEventType(eventTypeId)
          : (await getEvents())['events'] as List<Map<String, dynamic>>? ?? [];

      final pastEvents = events.where((event) {
        final endDate = _parseEventDate(event['EndDateTime']);
        return endDate != null && endDate.isBefore(now);
      }).toList();

      pastEvents.sort((a, b) {
        final aDate = _parseEventDate(a['StartDateTime']) ??
            DateTime.fromMillisecondsSinceEpoch(0);
        final bDate = _parseEventDate(b['StartDateTime']) ??
            DateTime.fromMillisecondsSinceEpoch(0);
        return bDate.compareTo(aDate);
      });

      return pastEvents.take(limit).map((event) {
        final assignedEquipment =
            event['assignedEquipment'] as List<dynamic>? ?? const [];
        return {
          'id': event['id']?.toString() ?? '',
          'name': (event['Name'] ?? '').toString(),
          'startDate': event['StartDateTime']?.toString() ?? '',
          'endDate': event['EndDateTime']?.toString() ?? '',
          'assignedEquipment': assignedEquipment,
          'assignedEquipmentCount': assignedEquipment.length,
        };
      }).toList();
    } catch (e) {
      DebugLog.error('[DataService] Error in getPastEventsForAssistant', e);
      throw Exception(
          'Erreur lors de la récupération des événements passés: $e');
    }
  }

  Map<String, dynamic> _normalizeAssistantEquipment(Map<String, dynamic> item) {
    return {
      'id': (item['id'] ?? '').toString(),
      'name': (item['name'] ?? item['id'] ?? '').toString(),
      'category': (item['category'] ?? '').toString(),
      'status': (item['status'] ?? '').toString(),
      'brand': item['brand']?.toString(),
      'model': item['model']?.toString(),
      'availableQuantity': item['availableQuantity'],
      'totalQuantity': item['totalQuantity'],
    };
  }

  DateTime? _parseEventDate(dynamic rawValue) {
    if (rawValue is String) {
      return DateTime.tryParse(rawValue);
    }
    return null;
  }

  // ============================================================================
  // USER - Current User
  // ============================================================================

  /// Récupère l'utilisateur actuellement authentifié avec son rôle
  Future<Map<String, dynamic>> 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<String, dynamic>;
    } 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<List<Map<String, dynamic>>> getAlerts() async {
    try {
      final result = await _apiService.call('getAlerts', {});
      final alerts = result['alerts'] as List<dynamic>?;
      if (alerts == null) return [];
      return alerts.map((e) => e as Map<String, dynamic>).toList();
    } catch (e) {
      throw Exception('Erreur lors de la récupération des alertes: $e');
    }
  }

  /// Marque une alerte comme lue
  Future<void> 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<void> 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<Map<String, dynamic>> 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<Map<String, dynamic>> 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
  // ============================================================================

  /// Récupère toutes les maintenances
  Future<List<Map<String, dynamic>>> getMaintenances(
      {String? equipmentId}) async {
    try {
      final data = <String, dynamic>{};
      if (equipmentId != null) data['equipmentId'] = equipmentId;

      final result = await _apiService.call('getMaintenances', data);
      final maintenances = result['maintenances'] as List<dynamic>?;
      if (maintenances == null) return [];
      return maintenances.map((e) => e as Map<String, dynamic>).toList();
    } catch (e) {
      throw Exception('Erreur lors de la récupération des maintenances: $e');
    }
  }

  /// Supprime une maintenance
  Future<void> deleteMaintenance(String maintenanceId) async {
    try {
      await _apiService
          .call('deleteMaintenance', {'maintenanceId': maintenanceId});
    } catch (e) {
      throw Exception('Erreur lors de la suppression de la maintenance: $e');
    }
  }

  /// Récupère les containers contenant un équipement
  Future<List<Map<String, dynamic>>> getContainersByEquipment(
      String equipmentId) async {
    try {
      final result = await _apiService.call('getContainersByEquipment', {
        'equipmentId': equipmentId,
      });
      final containers = result['containers'] as List<dynamic>?;
      if (containers == null) return [];
      return containers.map((e) => e as Map<String, dynamic>).toList();
    } catch (e) {
      throw Exception('Erreur lors de la récupération des containers: $e');
    }
  }

  // ============================================================================
  // USERS
  // ============================================================================

  /// Récupère tous les utilisateurs (selon permissions)
  Future<List<Map<String, dynamic>>> getUsers() async {
    try {
      final result = await _apiService.call('getUsers', {});
      final users = result['users'] as List<dynamic>?;
      if (users == null) return [];
      return users.map((e) => e as Map<String, dynamic>).toList();
    } catch (e) {
      throw Exception('Erreur lors de la récupération des utilisateurs: $e');
    }
  }

  /// Récupère un utilisateur spécifique
  Future<Map<String, dynamic>> getUser(String userId) async {
    try {
      final result = await _apiService.call('getUser', {'userId': userId});
      return result['user'] as Map<String, dynamic>;
    } catch (e) {
      throw Exception('Erreur lors de la récupération de l\'utilisateur: $e');
    }
  }

  /// Supprime un utilisateur (Auth + Firestore)
  Future<void> 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<void> updateUser(String userId, Map<String, dynamic> data) async {
    try {
      await _apiService.call('updateUser', {
        'userId': userId,
        'data': data,
      });
    } catch (e) {
      throw Exception('Erreur lors de la mise à jour de l\'utilisateur: $e');
    }
  }

  /// Crée un utilisateur avec invitation par email
  Future<Map<String, dynamic>> createUserWithInvite({
    required String email,
    required String firstName,
    required String lastName,
    String? phoneNumber,
    required String roleId,
  }) async {
    try {
      final result = await _apiService.call('createUserWithInvite', {
        'email': email,
        'firstName': firstName,
        'lastName': lastName,
        'phoneNumber': phoneNumber ?? '',
        'roleId': roleId,
      });
      return result;
    } catch (e) {
      throw Exception('Erreur lors de la création de l\'utilisateur: $e');
    }
  }
}
