using MiningService.Domain.Events;
using MiningService.Domain.Exceptions;
using MiningService.Domain.SeedWork;

namespace MiningService.Domain.AggregatesModel.ReferralAggregate;

/// <summary>
/// EN: Referral Aggregate Root - tracks referral relationships.
/// VI: Referral Aggregate Root - theo dõi quan hệ giới thiệu.
/// </summary>
public class Referral : Entity, IAggregateRoot
{
    #region Properties

    /// <summary>EN: Miner who made the referral / VI: Thợ đào thực hiện giới thiệu</summary>
    public Guid ReferrerId { get; private set; }

    /// <summary>EN: Miner who was referred / VI: Thợ đào được giới thiệu</summary>
    public Guid ReferredId { get; private set; }

    /// <summary>EN: Referral code used / VI: Mã giới thiệu đã sử dụng</summary>
    public string ReferralCode { get; private set; } = string.Empty;

    /// <summary>EN: Bonus rate for referrer (e.g., 0.25 = 25%) / VI: Tỷ lệ thưởng cho người giới thiệu</summary>
    public decimal BonusRate { get; private set; }

    /// <summary>EN: Whether referral is active (KYC verified) / VI: Giới thiệu có hoạt động không (KYC đã xác minh)</summary>
    public bool IsActive { get; private set; }

    /// <summary>EN: Referral level (1 = direct) / VI: Cấp giới thiệu (1 = trực tiếp)</summary>
    public int Level { get; private set; }

    /// <summary>EN: When referral was created / VI: Khi giới thiệu được tạo</summary>
    public DateTime CreatedAt { get; private set; }

    /// <summary>EN: When referral was activated / VI: Khi giới thiệu được kích hoạt</summary>
    public DateTime? ActivatedAt { get; private set; }

    #endregion

    // EF Core
    protected Referral() { }

    #region Factory

    /// <summary>
    /// EN: Create a new referral (inactive until KYC).
    /// VI: Tạo giới thiệu mới (chưa hoạt động cho đến khi KYC).
    /// </summary>
    public static Referral Create(
        Guid referrerId, 
        Guid referredId, 
        string referralCode,
        decimal bonusRate = 0.25m,
        int level = 1)
    {
        if (referrerId == referredId)
            throw new ReferralDomainException("Cannot refer yourself");

        return new Referral
        {
            Id = Guid.NewGuid(),
            ReferrerId = referrerId,
            ReferredId = referredId,
            ReferralCode = referralCode,
            BonusRate = bonusRate,
            IsActive = false, // Inactive until KYC
            Level = level,
            CreatedAt = DateTime.UtcNow,
            ActivatedAt = null
        };
    }

    #endregion

    #region Methods

    /// <summary>
    /// EN: Activate referral (after KYC verification).
    /// VI: Kích hoạt giới thiệu (sau khi xác minh KYC).
    /// </summary>
    public void Activate()
    {
        if (IsActive)
            throw new ReferralDomainException("Referral is already active");

        IsActive = true;
        ActivatedAt = DateTime.UtcNow;

        AddDomainEvent(new ReferralActivatedDomainEvent(Id, ReferrerId, ReferredId));
    }

    /// <summary>
    /// EN: Deactivate referral (fraud, account ban, etc).
    /// VI: Hủy kích hoạt giới thiệu (gian lận, cấm tài khoản, v.v.).
    /// </summary>
    public void Deactivate()
    {
        IsActive = false;
    }

    /// <summary>
    /// EN: Calculate bonus amount for referrer.
    /// VI: Tính số tiền thưởng cho người giới thiệu.
    /// </summary>
    public decimal CalculateBonus(decimal baseRate)
    {
        if (!IsActive) return 0;
        return baseRate * BonusRate;
    }

    #endregion
}
