#nullable disable using LinqToDB; using LinqToDB.EntityFrameworkCore; using EllieBot.Db.Models; namespace EllieBot.Modules.Gambling.Services; public sealed class UserBetStatsService : IEService { private const long RESET_MIN_PRICE = 1000; private const decimal RESET_TOTAL_MULTIPLIER = 0.002m; private readonly DbService _db; private readonly ICurrencyService _cs; public UserBetStatsService(DbService db, ICurrencyService cs) { _db = db; _cs = cs; } public async Task<long> GetResetStatsPriceAsync(ulong userId, GamblingGame? game) { await using var ctx = _db.GetDbContext(); var totalBet = await ctx.GetTable<UserBetStats>() .Where(x => x.UserId == userId && (game == null || x.Game == game)) .SumAsyncLinqToDB(x => x.TotalBet); return Math.Max(RESET_MIN_PRICE, (long)Math.Ceiling(totalBet * RESET_TOTAL_MULTIPLIER)); } public async Task<bool> ResetStatsAsync(ulong userId, GamblingGame? game) { var price = await GetResetStatsPriceAsync(userId, game); if (!await _cs.RemoveAsync(userId, price, new("betstats", "reset"))) { return false; } await using var ctx = _db.GetDbContext(); await ctx.GetTable<UserBetStats>() .DeleteAsync(x => x.UserId == userId && (game == null || x.Game == game)); return true; } public async Task ResetGamblingStatsAsync() { await using var ctx = _db.GetDbContext(); await ctx.GetTable<GamblingStats>() .DeleteAsync(); } public async Task<IReadOnlyList<UserBetStats>> GetWinLbAsync(int page) { ArgumentOutOfRangeException.ThrowIfNegative(page); await using var ctx = _db.GetDbContext(); return await ctx.GetTable<UserBetStats>() .OrderByDescending(x => x.MaxWin) .Skip(page * 10) .Take(10) .ToArrayAsyncLinqToDB(); } }