using System; using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using TOOHUCardAPI.Data.Enums; using TOOHUCardAPI.Data.Models; using TOOHUCardAPI.Data.Repositories; using TOOHUCardAPI.DTO; namespace TOOHUCardAPI.Data.Services { public class StoreService { private readonly ILogger _logger; private readonly UserRepository _userRepository; private readonly CardRepository _cardRepository; public StoreService(ILogger logger, UserRepository userRepository, CardRepository cardRepository) { _logger = logger; _userRepository = userRepository; _cardRepository = cardRepository; } private async Task AddPoints(int points, User user) { user.Point = Math.Max(0, user.Point + points); await _userRepository.UpdateUser(user); _logger.LogInformation("User with steamid {SteamId} was given {PointsGiven} points. New total: {PointsTotal}", user.SteamId, points, user.Point); } public async Task AwardPoints(long steamid, int points, string reason) { User user = await _userRepository.GetUser(steamid); await AddPoints(points, user); _logger.LogInformation("awarded {Points} points to {SteamId} for reason [\"{reason}\"]", points, steamid, reason); } public async Task SaveKeyTotal(long steamId, int keyTotal, int keyUseCount) { User user = await _userRepository.GetUser(steamId); _logger.LogInformation("User {SteamId} just stored some key total data, previous total and use: ({OldKeyTotal},{OldKeyUseCount}). new ({NewKeyTotal},{NewKeyUseCount})", user.SteamId, user.KeyTotal, user.KeyUseCount, keyTotal, keyUseCount); user.KeyTotal = keyTotal; user.KeyUseCount = keyUseCount; await _userRepository.UpdateUser(user); return user; } public async Task ChangePowerMaxTotal(long steamId, int amt) { User user = await _userRepository.GetUser(steamId); user.PowerMaxTotal = Math.Clamp(user.PowerMaxTotal + amt, 0, int.MaxValue); await _userRepository.UpdateUser(user); _logger.LogInformation("User {SteamId} changed the number of MaxPower items they had by {Amount}", user.SteamId, amt); return user.PowerMaxTotal; } public async Task LevelUpCard(long steamId, string itemName, int levelIncrease) { User user = await _userRepository.GetUser(steamId); Card card = await _cardRepository.GetCardByItemCode(itemName); CardLevel userCardLevel = user.CardLevels.Find(cl => cl.Card.ItemCode == itemName) ?? new CardLevel() { Card = card, Level = 0 }; int totalCost = (card.Quality == Rarity.Normal ? AppSettings.PointsPerLevelNormal : AppSettings.PointsPerLevel) * levelIncrease; if (user.Point < totalCost) { throw new InsufficientPointsException(); } if (!user.CardLevels.Contains(userCardLevel)) { user.CardLevels.Add(userCardLevel); } await AddPoints(-totalCost, user); userCardLevel.Level += levelIncrease; await _userRepository.UpdateUser(user); _logger.LogInformation("User with steamid {SteamId} leveled up card {CardName} to level {Level}", user.SteamId, card.CardName, userCardLevel.Level); return totalCost; } public async Task PurchaseMagicKey(int amt, long steamId) { int totalCost = AppSettings.PointsPerKey * amt; amt = Math.Clamp(amt, 0, AppSettings.MaxKeyPurchaseAmount); User user = await _userRepository.GetUser(steamId); if (user.Point < totalCost) { throw new InsufficientPointsException(); } await AddPoints(-totalCost, user); user.KeyTotal += amt; await _userRepository.UpdateUser(user); _logger.LogInformation("User with steamid {SteamId} purchased {NumberKeys} keys for {TotalCost} points. New point value is {NewPoints}", user.SteamId, amt, totalCost, user.Point); return totalCost; } public async Task GiveFirstWinBonus(long steamId) { User user = await _userRepository.GetUser(steamId); if (user.LastFirstWin.AddDays(1) > DateTime.Now) { throw new NotFirstWinException(); } int points = new Random().Next(AppSettings.FirstWinBonusPointsMin, AppSettings.FirstWinBonusPointsMax + 1); await AddPoints(points, user); user.LastFirstWin = DateTime.Now; await _userRepository.UpdateUser(user); _logger.LogInformation("User with steamid {SteamId} received first win of the day bonus, earning {BonusPoints} points. New value: {UserPoints}", user.SteamId, points, user.Point); return points; } } }