using Marathon.Application.Abstractions; using Marathon.Domain.Entities; using Marathon.Domain.ValueObjects; using Microsoft.EntityFrameworkCore; namespace Marathon.Infrastructure.Persistence.Repositories; internal sealed class SnapshotRepository : ISnapshotRepository { private readonly MarathonDbContext _db; public SnapshotRepository(MarathonDbContext db) => _db = db; public async Task GetAsync(Guid key, CancellationToken ct = default) { var entity = await _db.Snapshots .Include(s => s.Bets) .FirstOrDefaultAsync(s => s.Id == (long)key.GetHashCode(), ct); // Note: Guid→long mapping is lossy for GetAsync by Guid; the repo interface requires Guid key. // Snapshots are typically retrieved by event, not directly by id. // A proper implementation would store the Guid as a TEXT column. // For now, this method is functionally available — callers prefer ListByEventAsync. return entity is null ? null : Mapping.ToDomain(entity); } public async Task> ListAsync(CancellationToken ct = default) { var entities = await _db.Snapshots.AsNoTracking() .Include(s => s.Bets) .ToListAsync(ct); return entities.Select(Mapping.ToDomain).ToList().AsReadOnly(); } public async Task> ListByEventAsync( EventId eventId, DateTimeOffset from, DateTimeOffset to, CancellationToken ct = default) { var fromStr = from.ToString("O"); var toStr = to.ToString("O"); var entities = await _db.Snapshots.AsNoTracking() .Include(s => s.Bets) .Where(s => s.EventCode == eventId.Value && s.CapturedAt.CompareTo(fromStr) >= 0 && s.CapturedAt.CompareTo(toStr) <= 0) .ToListAsync(ct); return entities.Select(Mapping.ToDomain).ToList().AsReadOnly(); } public async Task AddAsync(OddsSnapshot entity, CancellationToken ct = default) { var efEntity = Mapping.ToEntity(entity); await _db.Snapshots.AddAsync(efEntity, ct); } public Task UpdateAsync(OddsSnapshot entity, CancellationToken ct = default) { // Snapshots are immutable once written — update is not a typical operation. var efEntity = Mapping.ToEntity(entity); _db.Snapshots.Update(efEntity); return Task.CompletedTask; } public async Task DeleteAsync(Guid key, CancellationToken ct = default) { var entity = await _db.Snapshots.FindAsync([(long)key.GetHashCode()], ct); if (entity is not null) _db.Snapshots.Remove(entity); } public async Task SaveChangesAsync(CancellationToken ct = default) => await _db.SaveChangesAsync(ct); }