import 'package:dartz/dartz.dart';

import '../../core/errors/failures.dart';
import '../entities/chat_message.dart';
import '../entities/conversation.dart';

/// Interface pour le repository du chat.
///
/// Cette interface définit les contrats que doit respecter tout repository
/// qui gère les données relatives aux conversations et aux messages de chat.
///
/// **Usage:**
/// ```dart
/// final result = await chatRepository.getConversations('userId');
/// result.fold(
///   (failure) => print('Erreur: $failure'),
///   (conversations) => print('${conversations.length} conversations'),
/// );
/// ```
abstract class ChatRepository {
  /// Récupère toutes les conversations d'un utilisateur.
  ///
  /// [userId] L'identifiant de l'utilisateur
  ///
  /// Returns [Right] avec la liste des conversations si succès,
  /// [Left] avec une [Failure] si erreur
  Future<Either<Failure, List<Conversation>>> getConversations(String userId);

  /// Récupère ou crée une conversation avec un utilisateur.
  ///
  /// [userId] L'identifiant de l'utilisateur actuel
  /// [participantId] L'identifiant de l'autre participant
  ///
  /// Returns [Right] avec la conversation si succès,
  /// [Left] avec une [Failure] si erreur
  Future<Either<Failure, Conversation>> getOrCreateConversation(
    String userId,
    String participantId,
  );

  /// Récupère les messages d'une conversation avec pagination.
  ///
  /// [conversationId] L'identifiant de la conversation
  /// [page] Le numéro de page (défaut: 0)
  /// [size] La taille de la page (défaut: 50)
  ///
  /// Returns [Right] avec la liste des messages si succès,
  /// [Left] avec une [Failure] si erreur
  Future<Either<Failure, List<ChatMessage>>> getMessages(
    String conversationId, {
    int page = 0,
    int size = 50,
  });

  /// Envoie un nouveau message.
  ///
  /// [senderId] L'identifiant de l'expéditeur
  /// [recipientId] L'identifiant du destinataire
  /// [content] Le contenu du message
  /// [messageType] Le type de message (text, image, video, audio, file)
  /// [mediaUrl] L'URL du média (optionnel)
  ///
  /// Returns [Right] avec le message créé si succès,
  /// [Left] avec une [Failure] si erreur
  Future<Either<Failure, ChatMessage>> sendMessage({
    required String senderId,
    required String recipientId,
    required String content,
    String? messageType,
    String? mediaUrl,
  });

  /// Marque un message comme lu.
  ///
  /// [messageId] L'identifiant du message
  ///
  /// Returns [Right] avec void si succès,
  /// [Left] avec une [Failure] si erreur
  Future<Either<Failure, void>> markMessageAsRead(String messageId);

  /// Marque tous les messages d'une conversation comme lus.
  ///
  /// [conversationId] L'identifiant de la conversation
  /// [userId] L'identifiant de l'utilisateur
  ///
  /// Returns [Right] avec void si succès,
  /// [Left] avec une [Failure] si erreur
  Future<Either<Failure, void>> markConversationAsRead(
    String conversationId,
    String userId,
  );

  /// Supprime un message.
  ///
  /// [messageId] L'identifiant du message
  ///
  /// Returns [Right] avec void si succès,
  /// [Left] avec une [Failure] si erreur
  Future<Either<Failure, void>> deleteMessage(String messageId);

  /// Supprime une conversation.
  ///
  /// [conversationId] L'identifiant de la conversation
  ///
  /// Returns [Right] avec void si succès,
  /// [Left] avec une [Failure] si erreur
  Future<Either<Failure, void>> deleteConversation(String conversationId);

  /// Récupère le nombre de messages non lus pour un utilisateur.
  ///
  /// [userId] L'identifiant de l'utilisateur
  ///
  /// Returns [Right] avec le nombre de messages non lus si succès,
  /// [Left] avec une [Failure] si erreur
  Future<Either<Failure, int>> getUnreadMessagesCount(String userId);
}
