import 'package:equatable/equatable.dart'; /// Entité de domaine représentant un événement. /// /// Cette classe est indépendante de toute infrastructure (API, BDD, etc.) /// et représente la logique métier pure selon Clean Architecture. class Event extends Equatable { const Event({ required this.id, required this.title, required this.description, required this.startDate, required this.location, required this.category, required this.creatorEmail, required this.creatorFirstName, required this.creatorLastName, required this.creatorProfileImageUrl, this.link, this.imageUrl, this.participantIds = const [], this.status = EventStatus.open, this.reactionsCount = 0, this.commentsCount = 0, this.sharesCount = 0, }); final String id; final String title; final String description; final DateTime startDate; final String location; final String category; final String? link; final String? imageUrl; // Informations sur le créateur final String creatorEmail; final String creatorFirstName; final String creatorLastName; final String creatorProfileImageUrl; // Participants et interactions final List participantIds; final EventStatus status; final int reactionsCount; final int commentsCount; final int sharesCount; /// Crée une copie de l'événement avec les champs modifiés Event copyWith({ String? id, String? title, String? description, DateTime? startDate, String? location, String? category, String? link, String? imageUrl, String? creatorEmail, String? creatorFirstName, String? creatorLastName, String? creatorProfileImageUrl, List? participantIds, EventStatus? status, int? reactionsCount, int? commentsCount, int? sharesCount, }) { return Event( id: id ?? this.id, title: title ?? this.title, description: description ?? this.description, startDate: startDate ?? this.startDate, location: location ?? this.location, category: category ?? this.category, link: link ?? this.link, imageUrl: imageUrl ?? this.imageUrl, creatorEmail: creatorEmail ?? this.creatorEmail, creatorFirstName: creatorFirstName ?? this.creatorFirstName, creatorLastName: creatorLastName ?? this.creatorLastName, creatorProfileImageUrl: creatorProfileImageUrl ?? this.creatorProfileImageUrl, participantIds: participantIds ?? this.participantIds, status: status ?? this.status, reactionsCount: reactionsCount ?? this.reactionsCount, commentsCount: commentsCount ?? this.commentsCount, sharesCount: sharesCount ?? this.sharesCount, ); } /// Retourne le nom complet du créateur String get creatorFullName => '$creatorFirstName $creatorLastName'; /// Retourne le nombre total de participants int get participantsCount => participantIds.length; /// Vérifie si l'événement est ouvert aux participations bool get isOpen => status == EventStatus.open; /// Vérifie si l'événement est fermé bool get isClosed => status == EventStatus.closed; /// Vérifie si l'événement est annulé bool get isCancelled => status == EventStatus.cancelled; @override List get props => [ id, title, description, startDate, location, category, link, imageUrl, creatorEmail, creatorFirstName, creatorLastName, creatorProfileImageUrl, participantIds, status, reactionsCount, commentsCount, sharesCount, ]; } /// Énumération des statuts possibles d'un événement enum EventStatus { open, closed, cancelled, completed; /// Convertit une chaîne en EventStatus static EventStatus fromString(String status) { switch (status.toLowerCase()) { case 'ouvert': case 'open': return EventStatus.open; case 'fermé': case 'ferme': case 'closed': return EventStatus.closed; case 'annulé': case 'annule': case 'cancelled': return EventStatus.cancelled; case 'terminé': case 'termine': case 'completed': return EventStatus.completed; default: return EventStatus.open; } } /// Convertit EventStatus en chaîne pour l'API String toApiString() { switch (this) { case EventStatus.open: return 'ouvert'; case EventStatus.closed: return 'fermé'; case EventStatus.cancelled: return 'annulé'; case EventStatus.completed: return 'terminé'; } } }