import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_storage/firebase_storage.dart'; import 'package:file_picker/file_picker.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; import 'package:em2rp/models/event_model.dart'; import 'package:em2rp/models/event_type_model.dart'; import 'package:em2rp/models/user_model.dart'; import 'package:em2rp/services/api_service.dart'; import 'package:em2rp/services/data_service.dart'; import 'package:em2rp/services/alert_service.dart'; import 'dart:developer' as developer; class EventFormService { static final ApiService _apiService = apiService; static final DataService _dataService = DataService(FirebaseFunctionsApiService()); // ============================================================================ // READ Operations - Utilise l'API (sécurisé avec permissions côté serveur) // ============================================================================ static Future> fetchEventTypes() async { developer.log('Fetching event types via API...', name: 'EventFormService'); try { final eventTypesData = await _dataService.getEventTypes(); final eventTypes = eventTypesData.map((data) => EventTypeModel.fromMap(data, data['id'] as String)).toList(); developer.log('${eventTypes.length} event types loaded.', name: 'EventFormService'); return eventTypes; } catch (e, s) { developer.log('Error fetching event types', name: 'EventFormService', error: e, stackTrace: s); throw Exception("Could not load event types. Please check permissions."); } } static Future> fetchUsers() async { try { final usersData = await _dataService.getUsers(); return usersData.map((data) => UserModel.fromMap(data, data['id'] as String)).toList(); } catch (e) { developer.log('Error fetching users', name: 'EventFormService', error: e); throw Exception("Could not load users."); } } // ============================================================================ // STORAGE - Reste inchangé (déjà via Cloud Function) // ============================================================================ static Future>> uploadFiles(List files) async { List> uploadedFiles = []; for (final file in files) { final fileBytes = file.bytes; final fileName = file.name; if (fileBytes != null) { final ref = FirebaseStorage.instance.ref().child( 'events/temp/${DateTime.now().millisecondsSinceEpoch}_$fileName'); final uploadTask = await ref.putData(fileBytes); final url = await uploadTask.ref.getDownloadURL(); uploadedFiles.add({'name': fileName, 'url': url}); } else { throw Exception("Impossible de lire le fichier $fileName"); } } return uploadedFiles; } static Future moveEventFileHttp({ required String sourcePath, required String destinationPath, }) async { final url = Uri.parse('https://us-central1-em2rp-951dc.cloudfunctions.net/moveEventFileV2'); final user = FirebaseAuth.instance.currentUser; final idToken = await user?.getIdToken(); final response = await http.post( url, headers: { 'Content-Type': 'application/json', if (idToken != null) 'Authorization': 'Bearer $idToken', }, body: jsonEncode({ 'data': { 'sourcePath': sourcePath, 'destinationPath': destinationPath, } }), ); if (response.statusCode == 200) { final data = jsonDecode(response.body); if (data['url'] != null) { return data['url'] as String; } else if (data['result'] != null && data['result']['url'] != null) { return data['result']['url'] as String; } return null; } else { print('Erreur Cloud Function: \n${response.body}'); return null; } } // ============================================================================ // CRUD Operations - Utilise le backend sécurisé // ============================================================================ static Future createEvent(EventModel event) async { try { final result = await _apiService.call('createEvent', event.toMap()); final eventId = result['id'] as String; // NOUVEAU : Créer alerte automatique pour les utilisateurs assignés try { await AlertService().createEventCreatedAlert( eventId: eventId, eventName: event.name, eventDate: event.startDateTime, ); developer.log('Alert created for new event: $eventId', name: 'EventFormService'); } catch (alertError) { // Ne pas bloquer la création de l'événement si l'alerte échoue developer.log('Warning: Could not create alert for event', name: 'EventFormService', error: alertError); } return eventId; } catch (e) { developer.log('Error creating event', name: 'EventFormService', error: e); rethrow; } } static Future updateEvent(EventModel event) async { try { if (event.id.isEmpty) { throw Exception("Cannot update event: Event ID is empty"); } developer.log('Updating event with ID: ${event.id}', name: 'EventFormService'); final eventData = event.toMap(); eventData['eventId'] = event.id; await _apiService.call('updateEvent', eventData); developer.log('Event updated successfully', name: 'EventFormService'); // NOUVEAU : Créer alerte automatique pour les utilisateurs assignés try { final currentUserId = FirebaseAuth.instance.currentUser?.uid; if (currentUserId != null) { await AlertService().createEventModifiedAlert( eventId: event.id, eventName: event.name, modification: 'Informations modifiées', ); developer.log('Alert created for modified event: ${event.id}', name: 'EventFormService'); } } catch (alertError) { // Ne pas bloquer la modification de l'événement si l'alerte échoue developer.log('Warning: Could not create alert for event modification', name: 'EventFormService', error: alertError); } } catch (e) { developer.log('Error updating event', name: 'EventFormService', error: e); rethrow; } } static Future deleteEvent(String eventId) async { try { await _apiService.call('deleteEvent', {'eventId': eventId}); } catch (e) { developer.log('Error deleting event', name: 'EventFormService', error: e); rethrow; } } static Future>> moveFilesToEvent( List> tempFiles, String eventId) async { List> newFiles = []; for (final file in tempFiles) { final fileName = file['name']!; final oldUrl = file['url']!; String sourcePath; final tempPattern = RegExp(r'events/temp/[^?]+'); final match = tempPattern.firstMatch(oldUrl); if (match != null) { sourcePath = match.group(0)!; } else { final tempFileName = Uri.decodeComponent(oldUrl.split('/').last.split('?').first); sourcePath = tempFileName; } final destinationPath = 'events/$eventId/$fileName'; final newUrl = await moveEventFileHttp( sourcePath: sourcePath, destinationPath: destinationPath, ); if (newUrl != null) { newFiles.add({'name': fileName, 'url': newUrl}); } else { newFiles.add({'name': fileName, 'url': oldUrl}); } } return newFiles; } static Future updateEventDocuments(String eventId, List> documents) async { try { if (eventId.isEmpty) { throw Exception("Event ID cannot be empty"); } developer.log('Updating event documents for ID: $eventId (${documents.length} documents)', name: 'EventFormService'); await _apiService.call('updateEvent', { 'eventId': eventId, 'documents': documents, }); developer.log('Event documents updated successfully', name: 'EventFormService'); } catch (e) { developer.log('Error updating event documents', name: 'EventFormService', error: e); throw Exception("Could not update event documents."); } } }