using SVSim.Database.Enums;
using SVSim.Database.Models;
using SVSim.Database.Services;
namespace SVSim.Database.Services.Inventory;
///
/// Scoped builder returned by . Queue spend +
/// grant operations; commit to save and assemble the .
///
/// Dispose without committing rolls back the underlying DB transaction and detaches any
/// in-memory mutations. Always wrap in await using.
///
///
public interface IInventoryTransaction : IAsyncDisposable
{
Viewer Viewer { get; }
bool IsFreeplay { get; }
///
/// Debits one of the four scalar wallets. Freeplay-aware for Crystal/Rupee/RedEther
/// (returns Success with the configured freeplay amount, balance unchanged); SpotPoint
/// always real. Returns with current balance on
/// failure; viewer state is not mutated on failure.
///
Task TrySpendAsync(SpendCurrency currency, long cost, CancellationToken ct = default);
///
/// Type-dispatched debit. Currencies (RedEther/Crystal/Rupy/SpotCardPoint) route to
/// ; Item decrements OwnedItemEntry.Count. Returns
/// whose PostStateTotal is the new wallet balance for
/// currencies and the remaining item count for Item.
///
Task TryDebitAsync(UserGoodsType type, long detailId, int num, CancellationToken ct = default);
Task> GrantAsync(UserGoodsType type, long detailId, int num, CancellationToken ct = default);
Task BackfillCardCosmeticsAsync(CancellationToken ct = default);
///
/// Freeplay-aware balance read against the live viewer; reflects any spends queued in
/// this transaction. Inside a transaction, use this; outside, use
/// .
///
long EffectiveBalance(SpendCurrency currency);
bool OwnsCard(long cardId);
bool OwnsCosmetic(CosmeticType type, int id);
Task CommitAsync(CancellationToken ct = default);
}