using AdsManagerService.Domain.SeedWork;

namespace AdsManagerService.Domain.AggregatesModel.AdSetAggregate;

/// <summary>
/// EN: Bid strategy for an Ad Set.
/// VI: Chiến lược giá thầu cho Ad Set.
/// </summary>
public class BidStrategy : ValueObject
{
    /// <summary>
    /// EN: Bid type (CPC, CPM, OCPM, Target Cost).
    /// VI: Loại giá thầu (CPC, CPM, OCPM, Target Cost).
    /// </summary>
    public BidType Type { get; private set; }

    /// <summary>
    /// EN: Bid amount (for manual bidding).
    /// VI: Số tiền giá thầu (cho trường hợp thầu thủ công).
    /// </summary>
    public decimal? BidAmount { get; private set; }

    /// <summary>
    /// EN: Target cost per result (for OCPM/Target Cost).
    /// VI: Chi phí mục tiêu mỗi kết quả (cho OCPM/Target Cost).
    /// </summary>
    public decimal? TargetCost { get; private set; }

    protected BidStrategy() { }

    public BidStrategy(BidType type, decimal? bidAmount = null, decimal? targetCost = null)
    {
        Type = type;
        BidAmount = bidAmount;
        TargetCost = targetCost;
    }

    /// <summary>
    /// EN: Create CPC (Cost Per Click) strategy.
    /// VI: Tạo chiến lược CPC (Chi phí mỗi Click).
    /// </summary>
    public static BidStrategy CPC(decimal bidAmount) => new(BidType.CPC, bidAmount);

    /// <summary>
    /// EN: Create CPM (Cost Per Mille) strategy.
    /// VI: Tạo chiến lược CPM (Chi phí mỗi 1000 hiển thị).
    /// </summary>
    public static BidStrategy CPM(decimal bidAmount) => new(BidType.CPM, bidAmount);

    /// <summary>
    /// EN: Create OCPM (Optimized CPM) strategy.
    /// VI: Tạo chiến lược OCPM (CPM tối ưu).
    /// </summary>
    public static BidStrategy OCPM(decimal targetCost) => new(BidType.OCPM, null, targetCost);

    /// <summary>
    /// EN: Create automatic bidding strategy.
    /// VI: Tạo chiến lược thầu tự động.
    /// </summary>
    public static BidStrategy Automatic() => new(BidType.Automatic);

    protected override IEnumerable<object> GetEqualityComponents()
    {
        yield return Type;
        yield return BidAmount ?? 0;
        yield return TargetCost ?? 0;
    }
}

/// <summary>
/// EN: Bid type enumeration.
/// VI: Enum loại giá thầu.
/// </summary>
public enum BidType
{
    /// <summary>EN: Cost Per Click / VI: Chi phí mỗi Click</summary>
    CPC = 1,

    /// <summary>EN: Cost Per Mille (1000 impressions) / VI: Chi phí mỗi 1000 hiển thị</summary>
    CPM = 2,

    /// <summary>EN: Optimized CPM / VI: CPM tối ưu</summary>
    OCPM = 3,

    /// <summary>EN: Target Cost per result / VI: Chi phí mục tiêu mỗi kết quả</summary>
    TargetCost = 4,

    /// <summary>EN: Automatic bidding / VI: Thầu tự động</summary>
    Automatic = 5
}
