using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using SVSim.Database.Models; using SVSim.Database.Models.Config; using SVSim.Database.Repositories.Card; using SVSim.Database.Repositories.Collectibles; namespace SVSim.Database.Services.Inventory; public sealed class InventoryService : IInventoryService { private readonly SVSimDbContext _db; private readonly IGameConfigService _config; private readonly ICardRepository _cards; private readonly ICollectionRepository _collection; private readonly ILogger _log; public InventoryService( SVSimDbContext db, IGameConfigService config, ICardRepository cards, ICollectionRepository collection, ILogger log) { _db = db; _config = config; _cards = cards; _collection = collection; _log = log; } public async Task BeginAsync( long viewerId, CancellationToken ct = default, Action? configure = null) { var loadCfg = new InventoryLoadConfig(); configure?.Invoke(loadCfg); IQueryable query = _db.Viewers .Include(v => v.Cards).ThenInclude(c => c.Card) .Include(v => v.Sleeves) .Include(v => v.Emblems) .Include(v => v.LeaderSkins) .Include(v => v.Degrees) .Include(v => v.MyPageBackgrounds) .Include(v => v.Items).ThenInclude(i => i.Item); foreach (var include in loadCfg.Includes) query = include(query); var viewer = await query .AsSplitQuery() .FirstOrDefaultAsync(v => v.Id == viewerId, ct) ?? throw new InventoryViewerNotFoundException(viewerId); var freeplay = _config.Get(); var dbTx = await _db.Database.BeginTransactionAsync(ct); return new InventoryTransaction(_db, dbTx, viewer, freeplay, _log); } // Stubs for later tasks. public Task> EffectiveOwnedCardsAsync(Viewer viewer, CancellationToken ct = default) => throw new NotImplementedException(); public Task EffectiveCosmeticsAsync(Viewer viewer, CancellationToken ct = default) => throw new NotImplementedException(); public long EffectiveBalance(Viewer viewer, SpendCurrency currency) => throw new NotImplementedException(); }