using System;
using System.Collections.Generic;
using ShiroginSDK.Runtime.Modules.Data.Scripts.Enums;
using ShiroginSDK.Runtime.Modules.Events;
using ShiroginSDK.Runtime.Services.Base;
using ShiroginSDK.Runtime.Services.Interfaces;
using UnityEngine;
namespace ShiroginSDK.Runtime.Modules.Data.Scripts
{
///
/// Manages all in-game currencies and economy statistics.
/// Handles earning, spending, and analytics updates for currency-related events.
///
[Serializable]
public class EconomyData : BaseData
{
// ---- Currencies ----
public int Gold;
public int Gems;
public int RewardedTicket;
public int Keys;
public int Energy;
public int Hearts;
// ---- Economy Stats ----
public long TotalGoldEarned;
public long TotalGoldSpent;
public int TotalAdsWatched;
public int TotalPurchases;
// Cached service reference
private IEventService _eventService;
public EconomyData()
{
_eventService = ServiceLocator.Get();
}
protected override string PrefsKey => "ECONOMY_DATA";
// ---- Currency Accessors ----
public int GetCurrency(CurrencyType type)
{
return type switch
{
CurrencyType.Gold => Gold,
CurrencyType.Gems => Gems,
CurrencyType.RewardedTicket => RewardedTicket,
CurrencyType.Keys => Keys,
CurrencyType.Energy => Energy,
CurrencyType.Hearts => Hearts,
_ => 0
};
}
// ---- Reward Granting ----
public void GrantReward(CurrencyType type, int amount)
{
if (amount <= 0) return;
var oldValue = GetCurrency(type);
AddCurrency(type, amount);
var newValue = GetCurrency(type);
// 🔔 Event dispatch
_eventService?.Invoke(new ShiroginEvents.Economy.CurrencyChangedEvent(type, oldValue, newValue));
Debug.Log($"[EconomyData] {type} +{amount} granted (old: {oldValue}, new: {newValue})");
}
public void GrantReward(CurrencyType type, int amount, string source = "unknown")
{
if (amount <= 0) return;
var oldValue = GetCurrency(type);
AddCurrency(type, amount);
var newValue = GetCurrency(type);
// 🔔 Event dispatch
_eventService?.Invoke(new ShiroginEvents.Economy.CurrencyChangedEvent(type, oldValue, newValue));
_eventService?.Invoke(new ShiroginEvents.Rewards.RewardClaimedEvent(type.ToString(), source));
// 📊 Analytics tracking
if (source == "iap" || source == "bundle")
AddPurchase();
else if (source == "ad")
AddAdWatch();
Debug.Log($"[EconomyData] +{amount} {type} granted from [{source}] → new total: {newValue}");
}
// ---- Currency Management ----
public void SetCurrency(CurrencyType type, int value)
{
value = Mathf.Max(0, value);
switch (type)
{
case CurrencyType.Gold: Gold = value; break;
case CurrencyType.Gems: Gems = value; break;
case CurrencyType.RewardedTicket: RewardedTicket = value; break;
case CurrencyType.Keys: Keys = value; break;
case CurrencyType.Energy: Energy = value; break;
case CurrencyType.Hearts: Hearts = value; break;
}
Save();
}
public void AddCurrency(CurrencyType type, int amount)
{
if (amount <= 0) return;
switch (type)
{
case CurrencyType.Gold:
Gold += amount;
TotalGoldEarned += amount;
break;
case CurrencyType.Gems: Gems += amount; break;
case CurrencyType.RewardedTicket: RewardedTicket += amount; break;
case CurrencyType.Keys: Keys += amount; break;
case CurrencyType.Energy: Energy += amount; break;
case CurrencyType.Hearts: Hearts += amount; break;
}
Save();
}
public bool HasEnough(CurrencyType type, int amount)
{
if (amount <= 0) return true;
return GetCurrency(type) >= amount;
}
public bool SpendCurrency(CurrencyType type, int amount)
{
if (!HasEnough(type, amount)) return false;
switch (type)
{
case CurrencyType.Gold:
Gold -= amount;
TotalGoldSpent += amount;
break;
case CurrencyType.Gems: Gems -= amount; break;
case CurrencyType.RewardedTicket: RewardedTicket -= amount; break;
case CurrencyType.Keys: Keys -= amount; break;
case CurrencyType.Energy: Energy -= amount; break;
case CurrencyType.Hearts: Hearts -= amount; break;
}
Save();
return true;
}
// ---- Multi-Currency Purchase ----
public bool TryMultiPurchase(Dictionary cost, Action onSuccess = null, Action onFail = null)
{
foreach (var kv in cost)
if (!HasEnough(kv.Key, kv.Value))
{
onFail?.Invoke();
return false;
}
foreach (var kv in cost)
SpendCurrency(kv.Key, kv.Value);
onSuccess?.Invoke();
return true;
}
public bool TryPurchase(int price, CurrencyType currency, Action onSuccess = null, Action onFail = null)
{
if (SpendCurrency(currency, price))
{
onSuccess?.Invoke();
return true;
}
onFail?.Invoke();
return false;
}
// ---- Analytics Tracking ----
public void AddAdWatch()
{
TotalAdsWatched++;
Save();
}
public void AddPurchase()
{
TotalPurchases++;
Save();
}
}
}