namespace MissionService.Domain.AggregatesModel.MissionAggregate;

using MissionService.Domain.SeedWork;

/// <summary>
/// EN: Reward configuration for a mission - Value Object
/// VI: Cấu hình phần thưởng cho mission - Value Object
/// </summary>
public class MissionReward : ValueObject
{
    /// <summary>EN: Points earned / VI: Điểm nhận được</summary>
    public decimal Points { get; private set; }
    
    /// <summary>EN: Mining rate boost percentage / VI: Phần trăm tăng tốc đào</summary>
    public decimal MiningBoostPercent { get; private set; }
    
    /// <summary>EN: Experience points / VI: Điểm kinh nghiệm</summary>
    public int ExperiencePoints { get; private set; }
    
    /// <summary>EN: Badge ID if awarded / VI: ID huy hiệu nếu được tặng</summary>
    public string? BadgeId { get; private set; }
    
    // EF Core constructor
    protected MissionReward() { }
    
    private MissionReward(decimal points, decimal miningBoostPercent, int experiencePoints, string? badgeId)
    {
        Points = points;
        MiningBoostPercent = miningBoostPercent;
        ExperiencePoints = experiencePoints;
        BadgeId = badgeId;
    }
    
    /// <summary>
    /// EN: Create a new mission reward configuration
    /// VI: Tạo cấu hình phần thưởng mission mới
    /// </summary>
    public static MissionReward Create(
        decimal points,
        decimal miningBoostPercent = 0,
        int experiencePoints = 0,
        string? badgeId = null)
    {
        if (points < 0)
            throw new ArgumentException("Points cannot be negative", nameof(points));
        if (miningBoostPercent < 0)
            throw new ArgumentException("Mining boost cannot be negative", nameof(miningBoostPercent));
        if (experiencePoints < 0)
            throw new ArgumentException("Experience points cannot be negative", nameof(experiencePoints));
            
        return new MissionReward(points, miningBoostPercent, experiencePoints, badgeId);
    }
    
    /// <summary>
    /// EN: Create points-only reward / VI: Tạo phần thưởng chỉ có điểm
    /// </summary>
    public static MissionReward PointsOnly(decimal points) => Create(points);
    
    protected override IEnumerable<object?> GetEqualityComponents()
    {
        yield return Points;
        yield return MiningBoostPercent;
        yield return ExperiencePoints;
        yield return BadgeId;
    }
}

/// <summary>
/// EN: Rule for mission completion - Entity
/// VI: Quy tắc hoàn thành mission - Entity
/// </summary>
public class MissionRule : Entity
{
    /// <summary>EN: Type of rule / VI: Loại quy tắc</summary>
    public string RuleType { get; private set; } = string.Empty;
    
    /// <summary>EN: Comparison operator / VI: Toán tử so sánh</summary>
    public string Operator { get; private set; } = string.Empty;
    
    /// <summary>EN: Target value / VI: Giá trị mục tiêu</summary>
    public string Value { get; private set; } = string.Empty;
    
    /// <summary>EN: Additional metadata as JSON / VI: Metadata bổ sung dạng JSON</summary>
    public string? Metadata { get; private set; }
    
    // EF Core constructor
    protected MissionRule() { }
    
    public MissionRule(string ruleType, string @operator, string value, string? metadata = null)
    {
        if (string.IsNullOrWhiteSpace(ruleType))
            throw new ArgumentException("Rule type is required", nameof(ruleType));
            
        RuleType = ruleType;
        Operator = @operator;
        Value = value;
        Metadata = metadata;
    }
    
    /// <summary>
    /// EN: Create a minimum duration rule (for video watching)
    /// VI: Tạo quy tắc thời lượng tối thiểu (cho xem video)
    /// </summary>
    public static MissionRule MinDuration(int seconds) 
        => new("Duration", ">=", seconds.ToString());
    
    /// <summary>
    /// EN: Create a minimum watch percentage rule
    /// VI: Tạo quy tắc phần trăm xem tối thiểu
    /// </summary>
    public static MissionRule MinWatchPercent(int percent) 
        => new("WatchPercent", ">=", percent.ToString());
    
    /// <summary>
    /// EN: Create a specific URL rule
    /// VI: Tạo quy tắc URL cụ thể
    /// </summary>
    public static MissionRule SpecificUrl(string url) 
        => new("Url", "==", url);
}
