using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Domain.Entities.Store;
///
/// 게임별 인앱 상품 SKU 정가 카탈로그. 파트너 결제 보고(ApiPurchase) 금액 검증용 —
/// 보고가가 정가와 다르면 ApiPurchase.PriceMismatched flag (등록은 통과, Admin 검토).
/// 카탈로그 미등록 SKU 는 검증 없이 통과.
///
public class GameProductCatalog
{
[ForeignKey(nameof(GameID))]
public virtual Game? Game { get; private set; }
[Key]
public int ID { get; private set; }
public int GameID { get; private set; }
/// 인앱 상품 SKU (예: "diamond_100"). (GameID, ProductID) UNIQUE.
public string ProductID { get; private set; } = default!;
/// 정가 (KRW)
public int Price { get; private set; }
public bool IsActive { get; private set; } = true;
public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; private set; }
private GameProductCatalog() { }
public static GameProductCatalog Create(int gameID, string productID, int price)
{
if (gameID <= 0)
{
throw new ArgumentOutOfRangeException(nameof(gameID));
}
ValidateProductID(productID);
ValidatePrice(price);
return new GameProductCatalog
{
GameID = gameID,
ProductID = productID.Trim(),
Price = price
};
}
public void Update(int price, bool isActive)
{
ValidatePrice(price);
Price = price;
IsActive = isActive;
UpdatedAt = DateTime.UtcNow;
}
private static void ValidateProductID(string productID)
{
if (string.IsNullOrWhiteSpace(productID))
{
throw new ArgumentException("ProductID is required.", nameof(productID));
}
if (productID.Length > 100)
{
throw new ArgumentOutOfRangeException(nameof(productID), "ProductID 는 100자 이하로 입력하세요.");
}
}
private static void ValidatePrice(int price)
{
if (price <= 0)
{
throw new ArgumentOutOfRangeException(nameof(price), "Price must be positive.");
}
}
}