namespace ChatService.Domain.AggregatesModel.ConversationAggregate;

using ChatService.Domain.SeedWork;

/// <summary>
/// EN: Repository interface for Conversation aggregate.
/// VI: Interface repository cho Conversation aggregate.
/// </summary>
public interface IConversationRepository : IRepository<Conversation>
{
    /// <summary>
    /// EN: Get conversation by ID with participants.
    /// VI: Lấy conversation theo ID với danh sách thành viên.
    /// </summary>
    Task<Conversation?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get conversation by ID with participants and recent messages.
    /// VI: Lấy conversation theo ID với thành viên và tin nhắn gần đây.
    /// </summary>
    Task<Conversation?> GetWithMessagesAsync(Guid id, int messageCount = 50, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get all conversations for a user.
    /// VI: Lấy tất cả conversations của một user.
    /// </summary>
    Task<IEnumerable<Conversation>> GetUserConversationsAsync(
        Guid userId, 
        int skip = 0, 
        int take = 20, 
        CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Find existing direct conversation between two users.
    /// VI: Tìm conversation trực tiếp đã tồn tại giữa hai users.
    /// </summary>
    Task<Conversation?> FindDirectConversationAsync(Guid user1Id, Guid user2Id, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get messages for a conversation with pagination.
    /// VI: Lấy tin nhắn cho một conversation với phân trang.
    /// </summary>
    Task<IEnumerable<Message>> GetMessagesAsync(
        Guid conversationId,
        int skip = 0,
        int take = 50,
        DateTime? before = null,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get unread message count for a user in a conversation.
    /// VI: Lấy số tin nhắn chưa đọc cho user trong một conversation.
    /// </summary>
    Task<int> GetUnreadCountAsync(Guid conversationId, Guid userId, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get total unread count across all conversations for a user.
    /// VI: Lấy tổng số tin chưa đọc trên tất cả conversations cho một user.
    /// </summary>
    Task<int> GetTotalUnreadCountAsync(Guid userId, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Add a new conversation.
    /// VI: Thêm một conversation mới.
    /// </summary>
    Conversation Add(Conversation conversation);

    /// <summary>
    /// EN: Update an existing conversation.
    /// VI: Cập nhật một conversation.
    /// </summary>
    void Update(Conversation conversation);

    /// <summary>
    /// EN: Get conversations for user with pagination and total count.
    /// VI: Lấy conversations cho user với phân trang và tổng số.
    /// </summary>
    Task<(IEnumerable<Conversation> Conversations, int TotalCount)> GetConversationsForUserAsync(
        Guid userId,
        int page = 1,
        int pageSize = 20,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get messages for a conversation with pagination and total count.
    /// VI: Lấy tin nhắn với phân trang và tổng số.
    /// </summary>
    Task<(IEnumerable<Message> Messages, int TotalCount)> GetMessagesPaginatedAsync(
        Guid conversationId,
        int page = 1,
        int pageSize = 50,
        DateTime? before = null,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get unread message count for a user in a conversation.
    /// VI: Lấy số tin nhắn chưa đọc cho user trong một conversation.
    /// </summary>
    Task<int> GetUnreadMessageCountAsync(Guid conversationId, Guid userId, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Check if user is participant in conversation.
    /// VI: Kiểm tra user có phải participant trong conversation.
    /// </summary>
    Task<bool> IsUserParticipantAsync(Guid conversationId, Guid userId, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get conversation by ID with all messages.
    /// VI: Lấy conversation theo ID với tất cả messages.
    /// </summary>
    Task<Conversation?> GetByIdWithMessagesAsync(Guid id, CancellationToken cancellationToken = default);
}
