using Microsoft.AspNetCore.Mvc; using SVSim.Database.Repositories.Viewer; using SVSim.EmulatedEntrypoint.Constants; using SVSim.EmulatedEntrypoint.Models.Dtos; using SVSim.EmulatedEntrypoint.Models.Dtos.Profile; namespace SVSim.EmulatedEntrypoint.Controllers; /// /// /profile/* — viewer-scoped profile read endpoint. Surfaces total rank-match wins /// and the per-class roster (level, exp, leader-skin selection). /// [Route("profile")] public sealed class ProfileController : SVSimController { private readonly IViewerRepository _viewerRepository; public ProfileController(IViewerRepository viewerRepository) => _viewerRepository = viewerRepository; [HttpPost("index")] public async Task> Index( [FromBody] ProfileIndexRequest _, CancellationToken ct) { var shortUdidClaim = User.Claims.FirstOrDefault(c => c.Type == ShadowverseClaimTypes.ShortUdidClaim)?.Value; if (shortUdidClaim is null || !long.TryParse(shortUdidClaim, out long shortUdid)) return Unauthorized(); var viewer = await _viewerRepository.GetViewerByShortUdid(shortUdid); if (viewer is null) return NotFound(); var skinsByClass = viewer.LeaderSkins .Where(s => s.ClassId.HasValue) .GroupBy(s => s.ClassId!.Value) .ToDictionary(g => g.Key, g => (IReadOnlyCollection)g.Select(s => s.Id).ToList()); var classes = viewer.Classes .Select(vc => new UserClass( vc, skinsByClass.GetValueOrDefault(vc.Class.Id, Array.Empty()))) .ToList(); return new ProfileIndexResponse { // TODO: when rank-match results are tracked, compute from viewer's rank history. UserRankMatchTotalWin = 0, UserClassList = classes, }; } }