using MembershipService.Domain.SeedWork;

namespace MembershipService.Domain.AggregatesModel.LevelAggregate;

/// <summary>
/// EN: Level definition aggregate root - configurable level rules.
/// VI: Level definition aggregate root - cấu hình level có thể tùy chỉnh.
/// </summary>
/// <remarks>
/// EN: Admin can customize level definitions through API.
/// Each level has a required EXP threshold and associated benefits.
/// VI: Admin có thể tùy chỉnh level definitions qua API.
/// Mỗi level có ngưỡng EXP yêu cầu và các benefits đi kèm.
/// </remarks>
public class LevelDefinition : Entity, IAggregateRoot
{
    private readonly List<LevelBenefit> _benefits = new();
    
    private int _levelNumber;
    private string _name;
    private int _requiredExp;
    private string? _description;
    private string? _iconUrl;
    private string? _badgeColor;
    private bool _isActive;
    private DateTime _createdAt;
    private DateTime _updatedAt;

    /// <summary>
    /// EN: Level number (1, 2, 3...).
    /// VI: Số thứ tự level (1, 2, 3...).
    /// </summary>
    public int LevelNumber => _levelNumber;

    /// <summary>
    /// EN: Level name (Bronze, Silver, Gold...).
    /// VI: Tên level (Bronze, Silver, Gold...).
    /// </summary>
    public string Name => _name;

    /// <summary>
    /// EN: Required EXP to reach this level.
    /// VI: EXP cần thiết để đạt level này.
    /// </summary>
    public int RequiredExp => _requiredExp;

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

    /// <summary>
    /// EN: Icon URL for the level badge.
    /// VI: URL icon cho badge level.
    /// </summary>
    public string? IconUrl => _iconUrl;

    /// <summary>
    /// EN: Badge color in hex format (#CD7F32, #FFD700...).
    /// VI: Màu badge dạng hex (#CD7F32, #FFD700...).
    /// </summary>
    public string? BadgeColor => _badgeColor;

    /// <summary>
    /// EN: Whether this level is active.
    /// VI: Level có đang active không.
    /// </summary>
    public bool IsActive => _isActive;

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

    /// <summary>
    /// EN: Last update timestamp.
    /// VI: Thời gian cập nhật cuối.
    /// </summary>
    public DateTime UpdatedAt => _updatedAt;

    /// <summary>
    /// EN: Benefits associated with this level.
    /// VI: Các benefits đi kèm với level này.
    /// </summary>
    public IReadOnlyCollection<LevelBenefit> Benefits => _benefits.AsReadOnly();

    /// <summary>
    /// EN: Private constructor for EF Core.
    /// VI: Constructor private cho EF Core.
    /// </summary>
    protected LevelDefinition()
    {
        _name = string.Empty;
    }

    /// <summary>
    /// EN: Create new level definition.
    /// VI: Tạo level definition mới.
    /// </summary>
    /// <param name="levelNumber">Level number (1, 2, 3...) / Số thứ tự level</param>
    /// <param name="name">Level name / Tên level</param>
    /// <param name="requiredExp">Required EXP / EXP yêu cầu</param>
    /// <param name="description">Description / Mô tả</param>
    /// <param name="iconUrl">Icon URL / URL icon</param>
    /// <param name="badgeColor">Badge color (hex) / Màu badge</param>
    public LevelDefinition(
        int levelNumber,
        string name,
        int requiredExp,
        string? description = null,
        string? iconUrl = null,
        string? badgeColor = null) : this()
    {
        if (levelNumber < 1)
            throw new ArgumentException("Level number must be positive", nameof(levelNumber));
        if (string.IsNullOrWhiteSpace(name))
            throw new ArgumentException("Level name cannot be empty", nameof(name));
        if (requiredExp < 0)
            throw new ArgumentException("Required EXP cannot be negative", nameof(requiredExp));

        Id = Guid.NewGuid();
        _levelNumber = levelNumber;
        _name = name;
        _requiredExp = requiredExp;
        _description = description;
        _iconUrl = iconUrl;
        _badgeColor = badgeColor;
        _isActive = true;
        _createdAt = DateTime.UtcNow;
        _updatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Update level name.
    /// VI: Cập nhật tên level.
    /// </summary>
    public void UpdateName(string name)
    {
        if (string.IsNullOrWhiteSpace(name))
            throw new ArgumentException("Level name cannot be empty", nameof(name));

        _name = name;
        _updatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Update required EXP threshold.
    /// VI: Cập nhật ngưỡng EXP yêu cầu.
    /// </summary>
    public void UpdateRequiredExp(int requiredExp)
    {
        if (requiredExp < 0)
            throw new ArgumentException("Required EXP cannot be negative", nameof(requiredExp));

        _requiredExp = requiredExp;
        _updatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Update level description.
    /// VI: Cập nhật mô tả level.
    /// </summary>
    public void UpdateDescription(string? description)
    {
        _description = description;
        _updatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Update icon URL.
    /// VI: Cập nhật URL icon.
    /// </summary>
    public void UpdateIconUrl(string? iconUrl)
    {
        _iconUrl = iconUrl;
        _updatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Update badge color.
    /// VI: Cập nhật màu badge.
    /// </summary>
    public void UpdateBadgeColor(string? badgeColor)
    {
        _badgeColor = badgeColor;
        _updatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Add a benefit to this level.
    /// VI: Thêm một benefit cho level này.
    /// </summary>
    public void AddBenefit(LevelBenefit benefit)
    {
        if (benefit == null)
            throw new ArgumentNullException(nameof(benefit));

        _benefits.Add(benefit);
        _updatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Remove a benefit from this level.
    /// VI: Xóa một benefit khỏi level này.
    /// </summary>
    public void RemoveBenefit(LevelBenefit benefit)
    {
        _benefits.Remove(benefit);
        _updatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Activate this level.
    /// VI: Kích hoạt level này.
    /// </summary>
    public void Activate()
    {
        _isActive = true;
        _updatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Deactivate this level (soft delete).
    /// VI: Vô hiệu hóa level này (xóa mềm).
    /// </summary>
    public void Deactivate()
    {
        _isActive = false;
        _updatedAt = DateTime.UtcNow;
    }
}
