import 'dart:convert'; import 'package:cloud_firestore/cloud_firestore.dart'; class Trip { final String? id; final String title; final String description; final String location; final DateTime startDate; final DateTime endDate; final double? budget; final List participants; final String createdBy; final DateTime createdAt; final DateTime updatedAt; final String status; Trip({ this.id, required this.title, required this.description, required this.location, required this.startDate, required this.endDate, this.budget, required this.participants, required this.createdBy, required this.createdAt, required this.updatedAt, this.status = 'draft', }); // NOUVELLE MÉTHODE HELPER pour convertir n'importe quel format de date static DateTime _parseDateTime(dynamic value) { if (value == null) return DateTime.now(); // Si c'est déjà un Timestamp Firebase if (value is Timestamp) { return value.toDate(); } // Si c'est un int (millisecondes depuis epoch) if (value is int) { return DateTime.fromMillisecondsSinceEpoch(value); } // Si c'est un String (ISO 8601) if (value is String) { return DateTime.parse(value); } // Si c'est déjà un DateTime if (value is DateTime) { return value; } // Par défaut return DateTime.now(); } // Constructeur pour créer un Trip depuis un Map (utile pour Firebase) factory Trip.fromMap(Map map, String id) { try { return Trip( id: id, title: map['title'] as String? ?? '', description: map['description'] as String? ?? '', location: map['location'] as String? ?? '', startDate: _parseDateTime(map['startDate']), endDate: _parseDateTime(map['endDate']), budget: (map['budget'] as num?)?.toDouble(), createdBy: map['createdBy'] as String? ?? '', participants: List.from(map['participants'] as List? ?? []), createdAt: _parseDateTime(map['createdAt']), updatedAt: _parseDateTime(map['updatedAt']), status: map['status'] as String? ?? 'draft', ); } catch (e) { rethrow; } } // MODIFIÉ : Convertir en Map avec Timestamp pour Firestore Map toMap() { return { 'title': title, 'description': description, 'location': location, 'startDate': Timestamp.fromDate(startDate), 'endDate': Timestamp.fromDate(endDate), 'budget': budget, 'participants': participants, 'createdBy': createdBy, 'createdAt': Timestamp.fromDate(createdAt), 'updatedAt': Timestamp.fromDate(updatedAt), 'status': status, }; } // Méthode pour convertir un Trip en JSON String toJson() { return json.encode(toMap()); } // Méthode pour créer une copie avec des modifications Trip copyWith({ String? id, String? title, String? description, String? location, DateTime? startDate, DateTime? endDate, double? budget, List? participants, String? createdBy, DateTime? createdAt, DateTime? updatedAt, String? status, }) { return Trip( id: id ?? this.id, title: title ?? this.title, description: description ?? this.description, location: location ?? this.location, startDate: startDate ?? this.startDate, endDate: endDate ?? this.endDate, budget: budget ?? this.budget, participants: participants ?? this.participants, createdBy: createdBy ?? this.createdBy, createdAt: createdAt ?? this.createdAt, updatedAt: updatedAt ?? this.updatedAt, status: status ?? this.status, ); } // Méthode pour obtenir la durée du voyage en jours int get durationInDays { return endDate.difference(startDate).inDays + 1; } // Méthode pour vérifier si le voyage est en cours bool get isActive { final now = DateTime.now(); return status == 'active' && now.isAfter(startDate) && now.isBefore(endDate.add(Duration(days: 1))); } // Méthode pour vérifier si le voyage est à venir bool get isUpcoming { final now = DateTime.now(); return status == 'active' && now.isBefore(startDate); } // Méthode pour vérifier si le voyage est terminé bool get isCompleted { final now = DateTime.now(); return status == 'completed' || (status == 'active' && now.isAfter(endDate)); } // Méthode pour obtenir le budget par participant double? get budgetPerParticipant { if (budget == null || participants.isEmpty) return null; return budget! / (participants.length + 1); } // Méthode pour obtenir le nombre total de participants (incluant le créateur) int get totalParticipants { return participants.length + 1; } // Méthode pour formater les dates String get formattedDates { return '${startDate.day}/${startDate.month}/${startDate.year} - ${endDate.day}/${endDate.month}/${endDate.year}'; } // Méthode pour obtenir le statut formaté String get formattedStatus { switch (status) { case 'draft': return 'Brouillon'; case 'active': return 'Actif'; case 'completed': return 'Terminé'; case 'cancelled': return 'Annulé'; default: return 'Inconnu'; } } @override String toString() { return 'Trip(id: $id, title: $title, location: $location, status: $status)'; } @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is Trip && other.id == id; } @override int get hashCode => id.hashCode; }