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<String> 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<String>? 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<Object?> 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é';
    }
  }
}

