using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Nuuru.Server.DTOs.Relation; using Nuuru.Server.Extensions; using Nuuru.Server.Models; using Nuuru.Server.Services; namespace Nuuru.Server.Controllers { [ApiController] [Route("api/relations")] public class UserRelationController : ControllerBase { private readonly IUserRelationService _relationService; private readonly IUserBadgeService _badgeService; private readonly ILogger _logger; public UserRelationController( IUserRelationService relationService, IUserBadgeService badgeService, ILogger logger) { _relationService = relationService; _badgeService = badgeService; _logger = logger; } [HttpPost("friends")] [Authorize] public async Task AddFriend([FromBody] AddRelationRequest request) { var userId = User.GetUserId(); if (userId == null) return Unauthorized(new { error = "User ID not found in token" }); var result = await _relationService.AddFriendAsync(userId.Value, request.TargetUserId); if (!result.Success) return BadRequest(new { error = result.ErrorMessage }); // Set target for audit log HttpContext.Items[AuditLog.TargetIdKey] = result.TargetUsername ?? result.TargetUserId?.ToString(); HttpContext.Items[AuditLog.TargetTypeKey] = "User"; return Ok(new { message = "Friend added successfully." }); } [HttpDelete("friends/{targetUserId:guid}")] [Authorize] public async Task RemoveFriend(Guid targetUserId) { var userId = User.GetUserId(); if (userId == null) return Unauthorized(new { error = "User ID not found in token" }); var result = await _relationService.RemoveFriendAsync(userId.Value, targetUserId); if (!result.Success) return BadRequest(new { error = result.ErrorMessage }); // Set target for audit log HttpContext.Items[AuditLog.TargetIdKey] = result.TargetUsername ?? result.TargetUserId?.ToString(); HttpContext.Items[AuditLog.TargetTypeKey] = "User"; return Ok(new { message = "Friend removed successfully." }); } [HttpGet("friends")] [Authorize] public async Task GetMyFriends() { var userId = User.GetUserId(); if (userId == null) return Unauthorized(new { error = "User ID not found in token" }); var friends = await _relationService.GetFriendsAsync(userId.Value); friends = await PopulateFriendRoleColors(friends); return Ok(friends); } [HttpGet("friends/{username}")] [AllowAnonymous] public async Task GetUserFriends(string username) { var friends = await _relationService.GetFriendsByUsernameAsync(username); friends = await PopulateFriendRoleColors(friends); return Ok(friends); } [HttpPost("enemies")] [Authorize] public async Task AddEnemy([FromBody] AddRelationRequest request) { var userId = User.GetUserId(); if (userId == null) return Unauthorized(new { error = "User ID not found in token" }); var result = await _relationService.AddEnemyAsync(userId.Value, request.TargetUserId); if (!result.Success) return BadRequest(new { error = result.ErrorMessage }); // Set target for audit log HttpContext.Items[AuditLog.TargetIdKey] = result.TargetUsername ?? result.TargetUserId?.ToString(); HttpContext.Items[AuditLog.TargetTypeKey] = "User"; return Ok(new { message = "Enemy added successfully." }); } [HttpDelete("enemies/{targetUserId:guid}")] [Authorize] public async Task RemoveEnemy(Guid targetUserId) { var userId = User.GetUserId(); if (userId == null) return Unauthorized(new { error = "User ID not found in token" }); var result = await _relationService.RemoveEnemyAsync(userId.Value, targetUserId); if (!result.Success) return BadRequest(new { error = result.ErrorMessage }); // Set target for audit log HttpContext.Items[AuditLog.TargetIdKey] = result.TargetUsername ?? result.TargetUserId?.ToString(); HttpContext.Items[AuditLog.TargetTypeKey] = "User"; return Ok(new { message = "Enemy removed successfully." }); } [HttpGet("enemies")] [Authorize] public async Task GetMyEnemies() { var userId = User.GetUserId(); if (userId == null) return Unauthorized(new { error = "User ID not found in token" }); var enemies = await _relationService.GetEnemiesAsync(userId.Value); enemies = await PopulateEnemyRoleColors(enemies); return Ok(enemies); } [HttpGet("enemies/{username}")] [AllowAnonymous] public async Task GetUserEnemies(string username) { var enemies = await _relationService.GetEnemiesByUsernameAsync(username); enemies = await PopulateEnemyRoleColors(enemies); return Ok(enemies); } [HttpGet("status/{targetUserId:guid}")] [Authorize] public async Task GetRelationStatus(Guid targetUserId) { var userId = User.GetUserId(); if (userId == null) return Unauthorized(new { error = "User ID not found in token" }); var status = await _relationService.GetRelationStatusAsync(userId.Value, targetUserId); return Ok(status); } private async Task> PopulateFriendRoleColors(IReadOnlyList friends) { if (friends.Count == 0) return friends; var displayInfoMap = await _badgeService.GetUsersDisplayInfoAsync(friends.Select(f => f.Id)); foreach (var friend in friends) { if (displayInfoMap.TryGetValue(friend.Id, out var info)) friend.RoleColor = info.RoleColor; } return friends; } private async Task> PopulateEnemyRoleColors(IReadOnlyList enemies) { if (enemies.Count == 0) return enemies; var displayInfoMap = await _badgeService.GetUsersDisplayInfoAsync(enemies.Select(e => e.Id)); foreach (var enemy in enemies) { if (displayInfoMap.TryGetValue(enemy.Id, out var info)) enemy.RoleColor = info.RoleColor; } return enemies; } } }