using IamService.Domain.SeedWork;

namespace IamService.Domain.AggregatesModel.GroupAggregate;

/// <summary>
/// EN: Group member entity representing a user's membership in a group.
/// VI: Entity thành viên nhóm đại diện cho việc user tham gia nhóm.
/// </summary>
public class GroupMember : Entity
{
    // EN: Private fields for encapsulation
    // VI: Fields private để đóng gói
    private Guid _userId;
    private Guid _groupId;
    private GroupRole _role = null!;
    private DateTime _joinedAt;
    private Guid? _addedByUserId;

    /// <summary>
    /// EN: User ID of the member.
    /// VI: ID của user thành viên.
    /// </summary>
    public Guid UserId => _userId;

    /// <summary>
    /// EN: Group ID this member belongs to.
    /// VI: ID nhóm mà thành viên thuộc về.
    /// </summary>
    public Guid GroupId => _groupId;

    /// <summary>
    /// EN: Role of the member in the group.
    /// VI: Vai trò của thành viên trong nhóm.
    /// </summary>
    public GroupRole Role => _role;

    /// <summary>
    /// EN: Role ID for EF Core mapping.
    /// VI: ID vai trò cho EF Core mapping.
    /// </summary>
    public int RoleId { get; private set; }

    /// <summary>
    /// EN: When the member joined the group.
    /// VI: Thời điểm thành viên tham gia nhóm.
    /// </summary>
    public DateTime JoinedAt => _joinedAt;

    /// <summary>
    /// EN: Who added this member to the group.
    /// VI: Ai đã thêm thành viên này vào nhóm.
    /// </summary>
    public Guid? AddedByUserId => _addedByUserId;

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

    /// <summary>
    /// EN: Create a new group member.
    /// VI: Tạo thành viên nhóm mới.
    /// </summary>
    public GroupMember(Guid groupId, Guid userId, GroupRole role, Guid? addedByUserId = null) : this()
    {
        if (groupId == Guid.Empty)
            throw new ArgumentException("Group ID cannot be empty", nameof(groupId));
        if (userId == Guid.Empty)
            throw new ArgumentException("User ID cannot be empty", nameof(userId));

        Id = Guid.NewGuid();
        _groupId = groupId;
        _userId = userId;
        _role = role ?? GroupRole.Member;
        RoleId = _role.Id;
        _joinedAt = DateTime.UtcNow;
        _addedByUserId = addedByUserId;
    }

    /// <summary>
    /// EN: Change the role of this member.
    /// VI: Thay đổi vai trò của thành viên này.
    /// </summary>
    public void ChangeRole(GroupRole newRole)
    {
        _role = newRole ?? throw new ArgumentNullException(nameof(newRole));
        RoleId = _role.Id;
    }

    /// <summary>
    /// EN: Check if this member is an owner.
    /// VI: Kiểm tra thành viên này có phải owner không.
    /// </summary>
    public bool IsOwner() => _role == GroupRole.Owner;

    /// <summary>
    /// EN: Check if this member is an admin or owner.
    /// VI: Kiểm tra thành viên này có phải admin hoặc owner không.
    /// </summary>
    public bool IsAdminOrOwner() => _role == GroupRole.Admin || _role == GroupRole.Owner;
}
