using WhatsAppService.Domain.SeedWork;

namespace WhatsAppService.Domain.AggregatesModel.ConversationAggregate;

/// <summary>
/// EN: Message entity owned by Conversation aggregate.
/// VI: Message entity thuộc sở hữu của Conversation aggregate.
/// </summary>
public class Message : Entity
{
    // EN: Private fields for encapsulation
    // VI: Fields private để đóng gói
    private Guid _conversationId;
    private string? _whatsAppMessageId;
    private string _direction = null!;
    private MessageContent _content = null!;
    private string _status = "sent";
    private DateTime _timestamp;

    /// <summary>
    /// EN: Parent conversation ID.
    /// VI: ID của conversation cha.
    /// </summary>
    public Guid ConversationId => _conversationId;

    /// <summary>
    /// EN: WhatsApp message ID from Meta API.
    /// VI: WhatsApp message ID từ Meta API.
    /// </summary>
    public string? WhatsAppMessageId => _whatsAppMessageId;

    /// <summary>
    /// EN: Message direction (inbound/outbound).
    /// VI: Hướng tin nhắn (inbound/outbound).
    /// </summary>
    public string Direction => _direction;

    /// <summary>
    /// EN: Message content (value object).
    /// VI: Nội dung tin nhắn (value object).
    /// </summary>
    public MessageContent Content => _content;

    /// <summary>
    /// EN: Message status (sent, delivered, read, failed).
    /// VI: Trạng thái tin nhắn (sent, delivered, read, failed).
    /// </summary>
    public string Status => _status;

    /// <summary>
    /// EN: Message timestamp.
    /// VI: Thời gian tin nhắn.
    /// </summary>
    public DateTime Timestamp => _timestamp;

    /// <summary>
    /// EN: Valid message directions.
    /// VI: Các hướng tin nhắn hợp lệ.
    /// </summary>
    public static class Directions
    {
        public const string Inbound = "inbound";
        public const string Outbound = "outbound";
    }

    /// <summary>
    /// EN: Valid message statuses.
    /// VI: Các trạng thái tin nhắn hợp lệ.
    /// </summary>
    public static class Statuses
    {
        public const string Sent = "sent";
        public const string Delivered = "delivered";
        public const string Read = "read";
        public const string Failed = "failed";
    }

    /// <summary>
    /// EN: Private constructor for EF Core.
    /// VI: Constructor private cho EF Core.
    /// </summary>
    protected Message()
    {
    }

    /// <summary>
    /// EN: Create a new message.
    /// VI: Tạo một tin nhắn mới.
    /// </summary>
    /// <param name="conversationId">EN: Parent conversation ID / VI: ID conversation cha</param>
    /// <param name="content">EN: Message content / VI: Nội dung tin nhắn</param>
    /// <param name="direction">EN: Message direction / VI: Hướng tin nhắn</param>
    /// <param name="whatsAppMessageId">EN: Optional WhatsApp message ID / VI: WhatsApp message ID tùy chọn</param>
    internal Message(
        Guid conversationId,
        MessageContent content,
        string direction,
        string? whatsAppMessageId = null) : this()
    {
        var validDirections = new[] { Directions.Inbound, Directions.Outbound };
        if (!validDirections.Contains(direction.ToLowerInvariant()))
            throw new ArgumentException($"Invalid message direction. Valid values: {string.Join(", ", validDirections)}");

        Id = Guid.NewGuid();
        _conversationId = conversationId;
        _content = content ?? throw new ArgumentNullException(nameof(content));
        _direction = direction.ToLowerInvariant();
        _whatsAppMessageId = whatsAppMessageId;
        _status = Statuses.Sent;
        _timestamp = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Update WhatsApp message ID after successful send.
    /// VI: Cập nhật WhatsApp message ID sau khi gửi thành công.
    /// </summary>
    /// <param name="whatsAppMessageId">EN: WhatsApp message ID / VI: WhatsApp message ID</param>
    internal void SetWhatsAppMessageId(string whatsAppMessageId)
    {
        _whatsAppMessageId = whatsAppMessageId;
    }

    /// <summary>
    /// EN: Update message status.
    /// VI: Cập nhật trạng thái tin nhắn.
    /// </summary>
    /// <param name="status">EN: New status / VI: Trạng thái mới</param>
    internal void UpdateStatus(string status)
    {
        var validStatuses = new[] { Statuses.Sent, Statuses.Delivered, Statuses.Read, Statuses.Failed };
        if (!validStatuses.Contains(status.ToLowerInvariant()))
            throw new ArgumentException($"Invalid message status. Valid values: {string.Join(", ", validStatuses)}");

        _status = status.ToLowerInvariant();
    }
}
