using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; using Knot.Modules.Chats.Application.DTOs; using Knot.Shared.Kernel; using System.Threading; using System.Threading.Tasks; using System; using Microsoft.AspNetCore.Http; using MediatR; using Knot.Modules.Chats.Application.Messages.GetMessages; using Knot.Modules.Chats.Application.Messages.SearchMessages; using Knot.Modules.Chats.Application.Messages.UploadFile; using Knot.Modules.Chats.Application.Messages.GetSharedMedia; using Knot.Modules.Chats.Application.Messages.Send; using System.Linq; namespace Host.Controllers; [Authorize] [ApiController] [Route("api/messages")] public sealed class MessagesController : ControllerBase { private readonly ISender _sender; private readonly IUserContext _userContext; public MessagesController(ISender sender, IUserContext userContext) { _sender = sender; _userContext = userContext; } [HttpGet("chat/{chatId:guid}")] public async Task GetMessages(Guid chatId, [FromQuery] string? cursor, CancellationToken ct = default) { var result = await _sender.Send(new GetMessagesQuery(_userContext.UserId, chatId, cursor), ct); if (result.IsFailure) { return BadRequest(result.Error.Description); } return Ok(result.Value); } [HttpGet("search")] public async Task GetSearch([FromQuery] string q, [FromQuery] Guid? chatId, CancellationToken ct) { var result = await _sender.Send(new SearchMessagesQuery(_userContext.UserId, q, chatId), ct); if (result.IsFailure) { return BadRequest(result.Error.Description); } return Ok(result.Value); } [HttpPost("upload")] public async Task UploadFile(IFormFile file, CancellationToken ct) { if (file == null || file.Length == 0) { return BadRequest("No file uploaded"); } using var stream = file.OpenReadStream(); var result = await _sender.Send(new UploadFileCommand(file.FileName, file.ContentType, file.Length, stream), ct); if (result.IsFailure) { if (result.Error.Code == "File.TooLarge") { return StatusCode(413, result.Error.Description); } return BadRequest(result.Error.Description); } return Ok(result.Value); } [HttpGet("chat/{chatId:guid}/shared")] public async Task GetSharedMedia(Guid chatId, [FromQuery] string? type, CancellationToken ct) { var result = await _sender.Send(new GetSharedMediaQuery(_userContext.UserId, chatId, type), ct); if (result.IsFailure) { return BadRequest(result.Error.Description); } return Ok(result.Value); } [HttpPost("chat/{chatId:guid}")] public async Task SendMessage(Guid chatId, [FromBody] SendMessageRequest request, CancellationToken ct) { var attachments = request.Attachments?.Select(a => new AttachmentRequest(a.Type, a.Url, a.FileName, a.FileSize)).ToList(); var command = new SendMessageCommand( chatId, _userContext.UserId, request.Content, request.Type, attachments, request.ReplyToId, request.Quote, request.ForwardedFromId); var result = await _sender.Send(command, ct); if (result.IsFailure) { return BadRequest(result.Error.Description); } return Ok(result.Value); } }