using System.Text.Json; using SVSim.Database; using SVSim.Database.Models; using SVSim.Database.Repositories.Globals; using SVSim.Database.Repositories.Viewer; using SVSim.Database.Services; using SVSim.EmulatedEntrypoint.Models.Dtos.Common.ArenaTwoPick; using SVSim.EmulatedEntrypoint.Models.Dtos.Responses.ArenaTwoPick; namespace SVSim.EmulatedEntrypoint.Services; public class ArenaTwoPickService : IArenaTwoPickService { private readonly IArenaTwoPickRunRepository _runs; private readonly IArenaTwoPickRewardRepository _rewards; private readonly IArenaTwoPickCardPoolService _pool; private readonly IGameConfigService _config; private readonly IViewerRepository _viewers; private readonly RewardGrantService _grants; private readonly IViewerEntitlements _entitlements; private readonly IRandom _rng; private readonly SVSimDbContext _db; public ArenaTwoPickService( IArenaTwoPickRunRepository runs, IArenaTwoPickRewardRepository rewards, IArenaTwoPickCardPoolService pool, IGameConfigService config, IViewerRepository viewers, RewardGrantService grants, IViewerEntitlements entitlements, IRandom rng, SVSimDbContext db) { _runs = runs; _rewards = rewards; _pool = pool; _config = config; _viewers = viewers; _grants = grants; _entitlements = entitlements; _rng = rng; _db = db; } public async Task GetTopAsync(long viewerId) { var run = await _runs.GetByViewerIdAsync(viewerId); if (run is null) return new TopResponseDto { EntryInfo = null }; var dto = new TopResponseDto { EntryInfo = ProjectEntryInfo(run, viewerId), BattleResults = ProjectBattleResults(run), }; if (run.ClassId != 0) { dto.ClassInfo = ProjectClassInfo(run); dto.DeckInfo = ProjectDeckInfo(run); if (run.WinCount > 0 || run.LossCount > 0) dto.LeaderSkinId = run.LeaderSkinId; } return dto; } public Task EntryAsync(long viewerId, int consumeItemType) => throw new NotImplementedException(); public Task ChooseClassAsync(long viewerId, int classId) => throw new NotImplementedException(); public Task ChooseCardAsync(long viewerId, long selectedId) => throw new NotImplementedException(); public Task RetireAsync(long viewerId) => throw new NotImplementedException(); public Task FinishAsync(long viewerId) => throw new NotImplementedException(); public Task RecordBattleResultAsync(long viewerId, bool isWin) => throw new NotImplementedException(); // --- projection helpers (kept internal so test subclasses could exercise if needed) --- internal static EntryInfoDto ProjectEntryInfo(ViewerArenaTwoPickRun run, long viewerId) => new() { Id = run.EntryId, ViewerId = viewerId, RewardScheduleId = run.RewardScheduleId, ChallengeId = run.ChallengeId, MaxBattleCount = run.MaxBattleCount, LeaderSkinId = run.LeaderSkinId, IsRetire = run.IsRetire ? 1 : 0, }; internal static BattleResultsDto ProjectBattleResults(ViewerArenaTwoPickRun run) { var bools = JsonSerializer.Deserialize>(run.ResultListJson) ?? new(); return new() { ResultList = bools.Select(b => b ? 1 : 0).ToList(), WinCount = run.WinCount, }; } internal static ClassInfoDto ProjectClassInfo(ViewerArenaTwoPickRun run) { var ids = JsonSerializer.Deserialize>(run.CandidateClassIdsJson) ?? new(); return new() { ClassId1 = ids.ElementAtOrDefault(0), ClassId2 = ids.ElementAtOrDefault(1), ClassId3 = ids.ElementAtOrDefault(2), SelectedClassId = run.ClassId, }; } internal static DeckInfoDto ProjectDeckInfo(ViewerArenaTwoPickRun run) { var cards = JsonSerializer.Deserialize>(run.SelectedCardIdsJson) ?? new(); return new() { TwoPickEntryId = run.EntryId, ClassId = run.ClassId, IsSelectCompleted = run.IsSelectCompleted, SelectedCardIds = cards, SelectTurn = run.SelectTurn == 0 ? 1 : run.SelectTurn, }; } }