using AdsBillingService.Domain.SeedWork;
using AdsBillingService.Domain.Exceptions;

namespace AdsBillingService.Domain.AggregatesModel.ChargeAggregate;

/// <summary>
/// EN: Ad charge aggregate root - individual ad impression/click charge.
/// VI: Ad charge aggregate root - phí riêng lẻ cho impression/click quảng cáo.
/// </summary>
public class AdCharge : Entity, IAggregateRoot
{
    private Guid _advertiserId;
    private Guid _campaignId;
    private Guid _adId;
    private ChargeType _chargeType;
    private decimal _amount;
    private string _currency;
    private DateTime _chargedAt;
    private bool _processed;

    public Guid AdvertiserId => _advertiserId;
    public Guid CampaignId => _campaignId;
    public Guid AdId => _adId;
    public ChargeType ChargeType => _chargeType;
    public decimal Amount => _amount;
    public string Currency => _currency;
    public DateTime ChargedAt => _chargedAt;
    public bool Processed => _processed;

    protected AdCharge() 
    { 
        _currency = "VND"; // Default value for EF Core
    }

    public AdCharge(
        Guid advertiserId,
        Guid campaignId,
        Guid adId,
        ChargeType chargeType,
        decimal amount,
        string currency = "VND")
    {
        if (amount <= 0)
            throw new AdsBillingDomainException("Charge amount must be positive");

        Id = Guid.NewGuid();
        _advertiserId = advertiserId;
        _campaignId = campaignId;
        _adId = adId;
        _chargeType = chargeType;
        _amount = amount;
        _currency = currency;
        _chargedAt = DateTime.UtcNow;
        _processed = false;
    }

    /// <summary>
    /// EN: Mark charge as processed (billeddebited from wallet).
    /// VI: Đánh dấu charge đã xử lý (đã trừ tiền từ ví).
    /// </summary>
    public void MarkAsProcessed()
    {
        _processed = true;
    }

    /// <summary>
    /// EN: Factory method for impression charge.
    /// VI: Factory method cho charge impression.
    /// </summary>
    public static AdCharge ForImpression(Guid advertiserId, Guid campaignId, Guid adId, decimal cpm)
    {
        return new AdCharge(advertiserId, campaignId, adId, ChargeType.Impression, cpm / 1000);
    }

    /// <summary>
    /// EN: Factory method for click charge.
    /// VI: Factory method cho charge click.
    /// </summary>
    public static AdCharge ForClick(Guid advertiserId, Guid campaignId, Guid adId, decimal cpc)
    {
        return new AdCharge(advertiserId, campaignId, adId, ChargeType.Click, cpc);
    }
}

/// <summary>
/// EN: Charge type enumeration.
/// VI: Enum loại charge.
/// </summary>
public enum ChargeType
{
    Impression = 1,
    Click = 2,
    Conversion = 3
}
