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());
}