using Microsoft.AspNetCore.Identity;
using IamService.Domain.SeedWork;

namespace IamService.Domain.AggregatesModel.RoleAggregate;

/// <summary>
/// EN: Application role entity extending ASP.NET Core Identity.
/// VI: Entity role mở rộng từ ASP.NET Core Identity.
/// </summary>
public class ApplicationRole : IdentityRole<Guid>, IAggregateRoot
{
    // EN: Private fields for encapsulation
    // VI: Fields private để đóng gói
    private string? _description;
    private DateTime _createdAt;
    private bool _isSystemRole;
    
    private readonly List<IDomainEvent> _domainEvents = [];

    /// <summary>
    /// EN: Role description.
    /// VI: Mô tả role.
    /// </summary>
    public string? Description => _description;

    /// <summary>
    /// EN: Creation timestamp.
    /// VI: Thời gian tạo.
    /// </summary>
    public DateTime CreatedAt => _createdAt;

    /// <summary>
    /// EN: Whether this is a system-defined role.
    /// VI: Role có phải là system role không.
    /// </summary>
    public bool IsSystemRole => _isSystemRole;

    /// <summary>
    /// EN: Domain events.
    /// VI: Domain events.
    /// </summary>
    public IReadOnlyCollection<IDomainEvent> DomainEvents => _domainEvents.AsReadOnly();

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

    /// <summary>
    /// EN: Create a new role.
    /// VI: Tạo role mới.
    /// </summary>
    public ApplicationRole(string name, string? description = null, bool isSystemRole = false) : this()
    {
        if (string.IsNullOrWhiteSpace(name))
            throw new ArgumentException("Role name cannot be empty", nameof(name));

        Id = Guid.NewGuid();
        Name = name;
        NormalizedName = name.ToUpperInvariant();
        _description = description;
        _isSystemRole = isSystemRole;
        _createdAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Update role information.
    /// VI: Cập nhật thông tin role.
    /// </summary>
    public void Update(string name, string? description)
    {
        if (string.IsNullOrWhiteSpace(name))
            throw new ArgumentException("Role name cannot be empty", nameof(name));

        Name = name;
        NormalizedName = name.ToUpperInvariant();
        _description = description;
    }

    /// <summary>
    /// EN: Add domain event.
    /// VI: Thêm domain event.
    /// </summary>
    public void AddDomainEvent(IDomainEvent domainEvent)
    {
        _domainEvents.Add(domainEvent);
    }

    /// <summary>
    /// EN: Clear domain events.
    /// VI: Xóa domain events.
    /// </summary>
    public void ClearDomainEvents()
    {
        _domainEvents.Clear();
    }
}
