/// Repository interface pour la communication
///
/// Contrat de données pour les messages, conversations et templates
library messaging_repository;

import 'package:dartz/dartz.dart';
import '../../../../core/error/failures.dart';
import '../entities/message.dart';
import '../entities/conversation.dart';
import '../entities/message_template.dart';

/// Interface du repository de messagerie
abstract class MessagingRepository {
  // === CONVERSATIONS ===

  /// Récupère toutes les conversations de l'utilisateur
  Future<Either<Failure, List<Conversation>>> getConversations({
    String? organizationId,
    bool includeArchived = false,
  });

  /// Récupère une conversation par son ID
  Future<Either<Failure, Conversation>> getConversationById(String conversationId);

  /// Crée une nouvelle conversation
  Future<Either<Failure, Conversation>> createConversation({
    required String name,
    required List<String> participantIds,
    String? organizationId,
    String? description,
  });

  /// Archive une conversation
  Future<Either<Failure, void>> archiveConversation(String conversationId);

  /// Marque une conversation comme lue
  Future<Either<Failure, void>> markConversationAsRead(String conversationId);

  /// Mute/démute une conversation
  Future<Either<Failure, void>> toggleMuteConversation(String conversationId);

  /// Pin/unpin une conversation
  Future<Either<Failure, void>> togglePinConversation(String conversationId);

  // === MESSAGES ===

  /// Récupère les messages d'une conversation
  Future<Either<Failure, List<Message>>> getMessages({
    required String conversationId,
    int? limit,
    String? beforeMessageId,
  });

  /// Envoie un message individuel
  Future<Either<Failure, Message>> sendMessage({
    required String conversationId,
    required String content,
    List<String>? attachments,
    MessagePriority priority = MessagePriority.normal,
  });

  /// Envoie un broadcast à toute l'organisation
  Future<Either<Failure, Message>> sendBroadcast({
    required String organizationId,
    required String subject,
    required String content,
    MessagePriority priority = MessagePriority.normal,
    List<String>? attachments,
  });

  /// Envoie un message ciblé par rôles
  Future<Either<Failure, Message>> sendTargetedMessage({
    required String organizationId,
    required List<String> targetRoles,
    required String subject,
    required String content,
    MessagePriority priority = MessagePriority.normal,
  });

  /// Marque un message comme lu
  Future<Either<Failure, void>> markMessageAsRead(String messageId);

  /// Édite un message
  Future<Either<Failure, Message>> editMessage({
    required String messageId,
    required String newContent,
  });

  /// Supprime un message
  Future<Either<Failure, void>> deleteMessage(String messageId);

  // === TEMPLATES ===

  /// Récupère tous les templates disponibles
  Future<Either<Failure, List<MessageTemplate>>> getTemplates({
    String? organizationId,
    TemplateCategory? category,
  });

  /// Récupère un template par son ID
  Future<Either<Failure, MessageTemplate>> getTemplateById(String templateId);

  /// Crée un nouveau template
  Future<Either<Failure, MessageTemplate>> createTemplate({
    required String name,
    required String description,
    required TemplateCategory category,
    required String subject,
    required String body,
    List<Map<String, dynamic>>? variables,
    String? organizationId,
  });

  /// Met à jour un template
  Future<Either<Failure, MessageTemplate>> updateTemplate({
    required String templateId,
    String? name,
    String? description,
    String? subject,
    String? body,
    bool? isActive,
  });

  /// Supprime un template
  Future<Either<Failure, void>> deleteTemplate(String templateId);

  /// Envoie un message à partir d'un template
  Future<Either<Failure, Message>> sendFromTemplate({
    required String templateId,
    required Map<String, String> variables,
    required List<String> recipientIds,
  });

  // === STATISTIQUES ===

  /// Récupère le nombre de messages non lus
  Future<Either<Failure, int>> getUnreadCount({String? organizationId});

  /// Récupère les statistiques de communication
  Future<Either<Failure, Map<String, dynamic>>> getMessagingStats({
    required String organizationId,
    DateTime? startDate,
    DateTime? endDate,
  });
}
