using Microsoft.AspNetCore.Mvc; using SVSim.Database.Repositories.Viewer; using SVSim.Database.Services.Guild; using SVSim.EmulatedEntrypoint.Models.Dtos.Common; using SVSim.EmulatedEntrypoint.Models.Dtos.Common.Guild; using SVSim.EmulatedEntrypoint.Models.Dtos.GuildChat; using SVSim.EmulatedEntrypoint.Models.Dtos.Requests; namespace SVSim.EmulatedEntrypoint.Controllers; /// /guild_chat/* — 7 endpoints. See docs/api-spec/endpoints/post-login/guild_chat-*.md. [Route("guild_chat")] public sealed class GuildChatController : SVSimController { private readonly IGuildChatService _chat; private readonly IViewerRepository _viewers; public GuildChatController(IGuildChatService chat, IViewerRepository viewers) { _chat = chat; _viewers = viewers; } [HttpPost("messages")] public async Task> Messages( [FromBody] GuildChatMessagesRequest req, CancellationToken ct) { if (!TryGetViewerId(out var viewerId)) return Unauthorized(); var window = await _chat.GetWindowAsync( viewerId, (int)req.StartMessageId, req.Direction, req.WaitInterval, ct); // Build chat_message list var chatMessages = window.Messages.Select(m => new ChatMessageDto { ViewerId = m.AuthorViewerId, MessageId = m.MessageId, MessageType = (int)m.MessageType, CreateTime = new DateTimeOffset(m.CreatedAt, TimeSpan.Zero).ToUnixTimeSeconds(), Message = m.Body, // deck / replay / room remain null until Task 17 }).ToList(); // Build deduplicated users[] catalog from message authors var authorIds = window.Messages .Select(m => m.AuthorViewerId) .Distinct() .ToList(); var profiles = await _viewers.LoadChatProfilesAsync(authorIds, ct); var users = authorIds.Select(vid => { profiles.TryGetValue(vid, out var p); return new ChatUserDto { ViewerId = vid, Name = p?.Name ?? "", EmblemId = p?.EmblemId ?? 100_000_000L, CountryCode = p?.CountryCode ?? "", Rank = p?.Rank ?? 1, DegreeId = p?.DegreeId ?? 0, }; }).ToList(); return new GuildChatMessagesResponse { MaintenanceCardList = new(), Users = users, ChatMessage = chatMessages, WaitInterval = window.WaitIntervalSeconds, }; } [HttpPost("post")] public async Task> Post([FromBody] GuildChatPostRequest req, CancellationToken ct) { if (!TryGetViewerId(out var viewerId)) return Unauthorized(); var result = await _chat.PostTextOrStampAsync(viewerId, req.Type, req.Message, ct); if (!result.Ok) return Ok(new { result_code = 2 }); return new GuildChatPostResponse(); } [HttpPost("add_deck")] public Task> AddDeck([FromBody] GuildChatAddDeckRequest req, CancellationToken ct) => Task.FromResult>(new EmptyResponse()); [HttpPost("delete_deck")] public Task> DeleteDeck([FromBody] GuildChatDeleteDeckRequest req, CancellationToken ct) => Task.FromResult>(new EmptyResponse()); [HttpPost("add_replay")] public Task> AddReplay([FromBody] GuildChatAddReplayRequest req, CancellationToken ct) => Task.FromResult>(new EmptyResponse()); [HttpPost("replay_detail")] public Task> ReplayDetail([FromBody] GuildChatReplayDetailRequest req, CancellationToken ct) => Task.FromResult>(new GuildChatReplayDetailResponse()); [HttpPost("deck_log")] public Task> DeckLog([FromBody] GuildChatDeckLogRequest req, CancellationToken ct) => Task.FromResult>(new GuildChatDeckLogResponse()); }