namespace ChatService.Domain.AggregatesModel.UserAggregate;

using ChatService.Domain.SeedWork;

/// <summary>
/// EN: Repository interface for ChatUser aggregate.
/// VI: Interface repository cho ChatUser aggregate.
/// </summary>
public interface IChatUserRepository : IRepository<ChatUser>
{
    /// <summary>
    /// EN: Get user by their IAM Service identity ID.
    /// VI: Lấy user theo IAM Service identity ID.
    /// </summary>
    Task<ChatUser?> GetByIdentityUserIdAsync(string identityUserId, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get user by their chat user ID.
    /// VI: Lấy user theo chat user ID.
    /// </summary>
    Task<ChatUser?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get user with their key bundle and one-time pre-keys.
    /// VI: Lấy user với key bundle và one-time pre-keys.
    /// </summary>
    Task<ChatUser?> GetWithKeysAsync(Guid id, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get multiple users by their IDs.
    /// VI: Lấy nhiều users theo danh sách ID.
    /// </summary>
    Task<IEnumerable<ChatUser>> GetByIdsAsync(IEnumerable<Guid> ids, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Check if user exists by identity ID.
    /// VI: Kiểm tra user tồn tại theo identity ID.
    /// </summary>
    Task<bool> ExistsByIdentityUserIdAsync(string identityUserId, CancellationToken cancellationToken = default);

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

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

    /// <summary>
    /// EN: Get key bundle for X3DH key exchange and consume one-time pre-key.
    /// VI: Lấy key bundle cho X3DH key exchange và consume one-time pre-key.
    /// </summary>
    Task<(string? IdentityPublicKey, string? SignedPreKey, string? SignedPreKeySignature, OneTimePreKey? OneTimePreKey)> 
        GetKeyBundleAsync(Guid userId, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Get count of available one-time pre-keys.
    /// VI: Lấy số lượng one-time pre-keys còn khả dụng.
    /// </summary>
    Task<int> GetAvailablePreKeyCountAsync(Guid userId, CancellationToken cancellationToken = default);
}
