import 'package:cloud_firestore/cloud_firestore.dart'; import '../data/models/trip.dart'; class TripService { final FirebaseFirestore _firestore = FirebaseFirestore.instance; static const String _tripsCollection = 'trips'; // Charger tous les voyages Future> loadTrips() async { try { final QuerySnapshot querySnapshot = await _firestore .collection(_tripsCollection) .orderBy('createdAt', descending: true) .get(); return querySnapshot.docs.map((doc) { final data = doc.data() as Map; return Trip.fromMap({...data, 'id': doc.id}); }).toList(); } catch (e) { print('Erreur lors du chargement des voyages: $e'); return []; } } // Ajouter un nouveau voyage Future addTrip(Trip trip) async { try { final tripData = trip.toMap(); // Retirer l'ID vide du map tripData.remove('id'); // Convertir les dates en Timestamp pour Firestore tripData['startDate'] = Timestamp.fromDate(trip.startDate); tripData['endDate'] = Timestamp.fromDate(trip.endDate); tripData['createdAt'] = FieldValue.serverTimestamp(); tripData['updatedAt'] = FieldValue.serverTimestamp(); await _firestore.collection(_tripsCollection).add(tripData); return true; } catch (e) { print('Erreur lors de l\'ajout du voyage: $e'); return false; } } // Stream pour écouter les voyages d'un utilisateur en temps réel Stream> getTripsStreamByUser(String userId, String userEmail) { print('=== STREAM CRÉÉ ==='); print('UserId: $userId'); return _firestore .collection(_tripsCollection) .snapshots() .map((snapshot) { final List trips = []; for (int i = 0; i < snapshot.docs.length; i++) { var doc = snapshot.docs[i]; try { final data = doc.data(); // Vérifier si l'utilisateur est impliqué dans ce voyage final String createdBy = data['createdBy']?.toString() ?? ''; final List participants = data['participants'] ?? []; bool userIsInvolved = false; String reason = ''; // L'utilisateur est le créateur if (createdBy == userId) { userIsInvolved = true; reason = 'Créateur du voyage'; } // L'utilisateur est dans la liste des participants (par ID uniquement) if (participants.contains(userId)) { userIsInvolved = true; reason = reason.isEmpty ? 'Participant par ID' : '$reason + Participant par ID'; } if (userIsInvolved) { final trip = _convertDocumentToTrip(doc.id, data); if (trip != null) { trips.add(trip); } } } catch (e, stackTrace) { print('Erreur lors du traitement du document ${doc.id}: $e'); print('StackTrace: $stackTrace'); } } // Trier par date de création (les plus récents en premier) trips.sort((a, b) { try { return b.createdAt.compareTo(a.createdAt); } catch (e) { print('Erreur lors du tri: $e'); return 0; } }); return trips; }).handleError((error, stackTrace) { print('Erreur dans le stream: $error'); print('StackTrace: $stackTrace'); return []; }); } // Obtenir les voyages d'un utilisateur (version simplifiée) Future> getTripsByUser(String userId) async { try { // Récupérer d'abord les voyages créés par l'utilisateur final QuerySnapshot createdTrips = await _firestore .collection(_tripsCollection) .where('createdBy', isEqualTo: userId) .get(); final List trips = []; for (var doc in createdTrips.docs) { try { final data = doc.data() as Map; final trip = _convertDocumentToTrip(doc.id, data); if (trip != null) { trips.add(trip); } } catch (e) { print('Erreur lors de la conversion du voyage créé ${doc.id}: $e'); } } // Trier par date de création trips.sort((a, b) { try { return b.createdAt.compareTo(a.createdAt); } catch (e) { return 0; } }); return trips; } catch (e) { print('Erreur lors de la récupération des voyages: $e'); return []; } } // Méthode helper pour convertir un document Firestore en Trip Trip? _convertDocumentToTrip(String docId, Map data) { try { // Créer une copie des données pour ne pas modifier l'original Map processedData = Map.from(data); // Convertir les Timestamps Firestore en String ISO if (processedData['createdAt'] is Timestamp) { processedData['createdAt'] = (processedData['createdAt'] as Timestamp).toDate().toIso8601String(); } if (processedData['updatedAt'] is Timestamp) { processedData['updatedAt'] = (processedData['updatedAt'] as Timestamp).toDate().toIso8601String(); } if (processedData['startDate'] is Timestamp) { processedData['startDate'] = (processedData['startDate'] as Timestamp).toDate().toIso8601String(); } if (processedData['endDate'] is Timestamp) { processedData['endDate'] = (processedData['endDate'] as Timestamp).toDate().toIso8601String(); } // Assurer que tous les champs requis sont présents processedData['id'] = docId; processedData['participants'] = processedData['participants'] ?? []; processedData['budget'] = (processedData['budget'] is num) ? (processedData['budget'] as num).toDouble() : 0.0; processedData['description'] = processedData['description'] ?? ''; processedData['status'] = processedData['status'] ?? 'draft'; final trip = Trip.fromMap(processedData); return trip; } catch (e, stackTrace) { print('Erreur lors de la conversion du document $docId: $e'); print('StackTrace: $stackTrace'); return null; } } // Mettre à jour un voyage Future updateTrip(Trip updatedTrip) async { try { final tripData = updatedTrip.toMap(); tripData['updatedAt'] = FieldValue.serverTimestamp(); tripData.remove('id'); // Retirer l'ID des données à mettre à jour await _firestore .collection(_tripsCollection) .doc(updatedTrip.id) .update(tripData); return true; } catch (e) { print('Erreur lors de la mise à jour du voyage: $e'); return false; } } // Supprimer un voyage Future deleteTrip(String tripId) async { try { await _firestore.collection(_tripsCollection).doc(tripId).delete(); return true; } catch (e) { print('Erreur lors de la suppression du voyage: $e'); return false; } } // Obtenir un voyage par son ID Future getTripById(String tripId) async { try { final DocumentSnapshot doc = await _firestore .collection(_tripsCollection) .doc(tripId) .get(); if (doc.exists) { final data = doc.data() as Map; return Trip.fromMap({...data, 'id': doc.id}); } return null; } catch (e) { print('Erreur lors de la récupération du voyage: $e'); return null; } } // Ajouter un participant à un voyage Future addParticipant(String tripId, String userId) async { try { await _firestore.collection(_tripsCollection).doc(tripId).update({ 'participants': FieldValue.arrayUnion([userId]), 'updatedAt': FieldValue.serverTimestamp(), }); return true; } catch (e) { print('Erreur lors de l\'ajout du participant: $e'); return false; } } // Retirer un participant d'un voyage Future removeParticipant(String tripId, String userId) async { try { await _firestore.collection(_tripsCollection).doc(tripId).update({ 'participants': FieldValue.arrayRemove([userId]), 'updatedAt': FieldValue.serverTimestamp(), }); return true; } catch (e) { print('Erreur lors du retrait du participant: $e'); return false; } } }