namespace ChatService.Domain.AggregatesModel.UserAggregate;

using ChatService.Domain.SeedWork;

/// <summary>
/// EN: One-time pre-key for X3DH protocol - consumed after first use.
/// VI: One-time pre-key cho X3DH protocol - được xóa sau khi sử dụng.
/// </summary>
public class OneTimePreKey : Entity
{
    /// <summary>
    /// EN: Key identifier used by client to reference this key.
    /// VI: Mã định danh key được client sử dụng để tham chiếu.
    /// </summary>
    public int KeyId { get; private set; }

    /// <summary>
    /// EN: The public key (Curve25519).
    /// VI: Public key (Curve25519).
    /// </summary>
    public string PublicKey { get; private set; }

    /// <summary>
    /// EN: Whether this key has been consumed.
    /// VI: Key này đã được sử dụng chưa.
    /// </summary>
    public bool IsUsed { get; private set; }

    /// <summary>
    /// EN: When this key was created.
    /// VI: Thời điểm key được tạo.
    /// </summary>
    public DateTime CreatedAt { get; private set; }

    /// <summary>
    /// EN: When this key was consumed (if applicable).
    /// VI: Thời điểm key được sử dụng (nếu có).
    /// </summary>
    public DateTime? UsedAt { get; private set; }

    /// <summary>
    /// EN: The user who owns this key.
    /// VI: User sở hữu key này.
    /// </summary>
    public Guid UserId { get; private set; }

    protected OneTimePreKey()
    {
        // EN: Required by EF Core
        // VI: Yêu cầu bởi EF Core
        PublicKey = string.Empty;
    }

    public OneTimePreKey(Guid userId, int keyId, string publicKey)
    {
        if (string.IsNullOrWhiteSpace(publicKey))
            throw new ArgumentException("Public key is required", nameof(publicKey));

        Id = Guid.NewGuid();
        UserId = userId;
        KeyId = keyId;
        PublicKey = publicKey;
        IsUsed = false;
        CreatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Mark this key as consumed.
    /// VI: Đánh dấu key này đã được sử dụng.
    /// </summary>
    public void MarkAsUsed()
    {
        if (IsUsed)
            throw new InvalidOperationException("One-time pre-key has already been used");

        IsUsed = true;
        UsedAt = DateTime.UtcNow;
    }
}
