/// Entité métier Message
///
/// Représente un message dans le système de communication UnionFlow
library message;

import 'package:equatable/equatable.dart';

/// Type de message
enum MessageType {
  /// Message individuel (membre à membre)
  individual,

  /// Broadcast organisation (OrgAdmin → tous)
  broadcast,

  /// Message ciblé par rôle (Moderator → groupe)
  targeted,

  /// Notification système
  system,
}

/// Statut de lecture du message
enum MessageStatus {
  /// Envoyé mais non lu
  sent,

  /// Livré (reçu par le serveur)
  delivered,

  /// Lu par le destinataire
  read,

  /// Échec d'envoi
  failed,
}

/// Priorité du message
enum MessagePriority {
  /// Priorité normale
  normal,

  /// Priorité élevée (important)
  high,

  /// Priorité urgente (critique)
  urgent,
}

/// Entité Message
class Message extends Equatable {
  final String id;
  final String conversationId;
  final String senderId;
  final String senderName;
  final String? senderAvatar;
  final String content;
  final MessageType type;
  final MessageStatus status;
  final MessagePriority priority;
  final List<String> recipientIds;
  final List<String>? recipientRoles;
  final String? organizationId;
  final DateTime createdAt;
  final DateTime? readAt;
  final Map<String, dynamic>? metadata;
  final List<String>? attachments;
  final bool isEdited;
  final DateTime? editedAt;
  final bool isDeleted;

  const Message({
    required this.id,
    required this.conversationId,
    required this.senderId,
    required this.senderName,
    this.senderAvatar,
    required this.content,
    required this.type,
    required this.status,
    this.priority = MessagePriority.normal,
    required this.recipientIds,
    this.recipientRoles,
    this.organizationId,
    required this.createdAt,
    this.readAt,
    this.metadata,
    this.attachments,
    this.isEdited = false,
    this.editedAt,
    this.isDeleted = false,
  });

  /// Vérifie si le message a été lu
  bool get isRead => status == MessageStatus.read;

  /// Vérifie si le message est urgent
  bool get isUrgent => priority == MessagePriority.urgent;

  /// Vérifie si le message est un broadcast
  bool get isBroadcast => type == MessageType.broadcast;

  /// Vérifie si le message a des pièces jointes
  bool get hasAttachments => attachments != null && attachments!.isNotEmpty;

  /// Copie avec modifications
  Message copyWith({
    String? id,
    String? conversationId,
    String? senderId,
    String? senderName,
    String? senderAvatar,
    String? content,
    MessageType? type,
    MessageStatus? status,
    MessagePriority? priority,
    List<String>? recipientIds,
    List<String>? recipientRoles,
    String? organizationId,
    DateTime? createdAt,
    DateTime? readAt,
    Map<String, dynamic>? metadata,
    List<String>? attachments,
    bool? isEdited,
    DateTime? editedAt,
    bool? isDeleted,
  }) {
    return Message(
      id: id ?? this.id,
      conversationId: conversationId ?? this.conversationId,
      senderId: senderId ?? this.senderId,
      senderName: senderName ?? this.senderName,
      senderAvatar: senderAvatar ?? this.senderAvatar,
      content: content ?? this.content,
      type: type ?? this.type,
      status: status ?? this.status,
      priority: priority ?? this.priority,
      recipientIds: recipientIds ?? this.recipientIds,
      recipientRoles: recipientRoles ?? this.recipientRoles,
      organizationId: organizationId ?? this.organizationId,
      createdAt: createdAt ?? this.createdAt,
      readAt: readAt ?? this.readAt,
      metadata: metadata ?? this.metadata,
      attachments: attachments ?? this.attachments,
      isEdited: isEdited ?? this.isEdited,
      editedAt: editedAt ?? this.editedAt,
      isDeleted: isDeleted ?? this.isDeleted,
    );
  }

  @override
  List<Object?> get props => [
    id,
    conversationId,
    senderId,
    senderName,
    senderAvatar,
    content,
    type,
    status,
    priority,
    recipientIds,
    recipientRoles,
    organizationId,
    createdAt,
    readAt,
    metadata,
    attachments,
    isEdited,
    editedAt,
    isDeleted,
  ];
}
