using Govor.Application.Interfaces; using Govor.Application.Interfaces.Infrastructure.Extensions; using Govor.Core.Models; using Govor.Core.Repositories.PrivateChats; using Govor.Core.Repositories.Users; using Govor.Data.Repositories.Exceptions; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Govor.API.Controllers; [ApiController] [Authorize(Roles = "Admin, User")] [Route("api")] public class PrivateChatController : Controller { private readonly ICurrentUserService _currentUser; private readonly IUsersRepository _usersRepository; private readonly IVerifyFriendship _verifyFriendship; private readonly IPrivateChatsRepository _privateChats; private readonly ILogger _logger; public PrivateChatController( ICurrentUserService currentUser, IUsersRepository usersRepository, IVerifyFriendship verifyFriendship, IPrivateChatsRepository privateChats, ILogger logger) { _currentUser = currentUser; _usersRepository = usersRepository; _verifyFriendship = verifyFriendship; _privateChats = privateChats; _logger = logger; } [HttpGet("user/{friendId:guid}/private-chat")] public async Task GetChatByFriendId(Guid friendId) { try { var currentId = _currentUser.GetCurrentUserId(); if (!await _usersRepository.ExistsByIdAsync(friendId)) { _logger.LogWarning("User not exist {0}", friendId); return NotFound("User not exist."); } await _verifyFriendship.VerifyAsync(currentId, friendId); var chatId = await GetPrivateChatsIdAsync(currentId, friendId); return Ok(chatId); } catch (UnauthorizedAccessException ex) { _logger.LogWarning(ex.Message); return Forbid(ex.Message); } catch (NotFoundException ex) { _logger.LogWarning(ex, ex.Message); return BadRequest(ex.Message); } catch (ArgumentException ex) { _logger.LogWarning(ex, ex.Message); return BadRequest(ex.Message); } catch (Exception ex) { _logger.LogError(ex, ex.Message); return StatusCode(500, "Unexpected Error! Please try again later."); } } private async Task GetPrivateChatsIdAsync(Guid userA, Guid userB) { Guid recipientId; // Makes new PrivateChat if not exist if (!_privateChats.Exist(userA, userB)) { recipientId = Guid.NewGuid(); await _privateChats.AddAsync(new PrivateChat() { Id = recipientId, UserAId = userA, UserBId = userB }); } else { recipientId = (await _privateChats.GetByMembersAsync(userA, userB)).Id; } return recipientId; } }