import 'package:em2rp/services/api_service.dart';

/// Repository pour gérer toutes les opérations sur les événements.
class EventRepository {
  final ApiService _apiService;

  EventRepository(this._apiService);

  /// 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 un événement
  Future<void> updateEvent(String eventId, Map<String, dynamic> data) async {
    try {
      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');
    }
  }

  /// 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');
    }
  }

  /// 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('[EventRepository] 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(
          '[EventRepository] Events loaded for $year-$month: ${events.length} events');

      return {
        'events': events.map((e) => e as Map<String, dynamic>).toList(),
        'users': users,
      };
    } catch (e) {
      print('[EventRepository] 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('[EventRepository] 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(
          '[EventRepository] Event loaded with ${equipments.length} equipments and ${containers.length} containers');

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