using Microsoft.EntityFrameworkCore; using SVSim.Database.Models; namespace SVSim.Database.Repositories.Pack; public class PackRepository : IPackRepository { private readonly SVSimDbContext _db; public PackRepository(SVSimDbContext db) { _db = db; } public async Task> GetActivePacks(DateTime now) => await _db.Packs .Include(p => p.ChildGachas) .Include(p => p.Banners) .Where(p => p.CommenceDate <= now && p.CompleteDate >= now) .ToListAsync(); public async Task GetPack(int parentGachaId) => await _db.Packs .Include(p => p.ChildGachas) .Include(p => p.Banners) .FirstOrDefaultAsync(p => p.Id == parentGachaId); public async Task> GetOpenCountsForViewer(long viewerId) { var viewer = await _db.Viewers .Include(v => v.PackOpenCounts) .FirstOrDefaultAsync(v => v.Id == viewerId); return viewer?.PackOpenCounts.ToDictionary(p => p.PackId) ?? new(); } public async Task IncrementOpenCount(long viewerId, int parentGachaId, int by) { var viewer = await _db.Viewers .Include(v => v.PackOpenCounts) .FirstAsync(v => v.Id == viewerId); var row = viewer.PackOpenCounts.FirstOrDefault(p => p.PackId == parentGachaId); if (row is null) { viewer.PackOpenCounts.Add(new ViewerPackOpenCount { PackId = parentGachaId, OpenCount = by }); } else { row.OpenCount += by; } await _db.SaveChangesAsync(); } public async Task MarkDailyFreeUsed(long viewerId, int parentGachaId, DateTime when) { var viewer = await _db.Viewers .Include(v => v.PackOpenCounts) .FirstAsync(v => v.Id == viewerId); var row = viewer.PackOpenCounts.FirstOrDefault(p => p.PackId == parentGachaId); if (row is null) { viewer.PackOpenCounts.Add(new ViewerPackOpenCount { PackId = parentGachaId, OpenCount = 0, LastDailyFreeAt = when }); } else { row.LastDailyFreeAt = when; } await _db.SaveChangesAsync(); } public async Task GrantCardsToViewer(long viewerId, IEnumerable cardIds) { var viewer = await _db.Viewers .Include(v => v.Cards).ThenInclude(c => c.Card) .FirstAsync(v => v.Id == viewerId); var byId = viewer.Cards.ToDictionary(c => c.Card.Id); foreach (var grp in cardIds.GroupBy(id => id)) { if (byId.TryGetValue(grp.Key, out var existing)) { existing.Count += grp.Count(); } else { // Look up the card by id and attach it so we don't insert a phantom Card row. var card = await _db.Cards.FirstAsync(c => c.Id == grp.Key); var owned = new OwnedCardEntry { Card = card, Count = grp.Count(), IsProtected = false }; viewer.Cards.Add(owned); byId[grp.Key] = owned; } } await _db.SaveChangesAsync(); } }