using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using UniVerse.Application.DTOs.Common; using UniVerse.Application.DTOs.Users; using UniVerse.Application.Interfaces; using UniVerse.Domain.Enums; using System.Security.Claims; namespace UniVerse.Api.Controllers; [ApiController] [Route("api/v1/users")] [Authorize] public class UsersController : ControllerBase { private readonly IUserService _users; private readonly IReviewService _reviews; private readonly IGamificationService _gamification; public UsersController(IUserService users, IReviewService reviews, IGamificationService gamification) { _users = users; _reviews = reviews; _gamification = gamification; } private int CurrentUserId => int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub") ?? "0"); [HttpGet("{id:int}")] public async Task> Get(int id) => Ok(await _users.GetByIdAsync(id)); [HttpPut("{id:int}")] public async Task> Update(int id, [FromBody] UpdateUserRequest req) { if (CurrentUserId != id && !User.IsInRole("Admin")) return Forbid(); return Ok(await _users.UpdateProfileAsync(id, req)); } [HttpGet("{id:int}/stats")] public async Task> Stats(int id) => Ok(await _users.GetStatsAsync(id)); [HttpGet("{id:int}/enrollments")] public async Task Enrollments(int id, [FromQuery] PaginationRequest pagination) { if (CurrentUserId != id && !User.IsInRole("Admin")) return Forbid(); // Delegate to lecture service would be more proper, but returning reviews for now return Ok(); } [HttpGet("{id:int}/reviews")] public async Task Reviews(int id, [FromQuery] PaginationRequest pagination) => Ok(await _reviews.GetByUserAsync(id, pagination)); [HttpGet("{id:int}/achievements")] public async Task Achievements(int id) => Ok(await _gamification.GetUserAchievementsAsync(id)); [HttpGet("{id:int}/transactions")] public async Task Transactions(int id, [FromQuery] PaginationRequest pagination) { if (CurrentUserId != id && !User.IsInRole("Admin")) return Forbid(); return Ok(await _gamification.GetTransactionsAsync(id, pagination)); } [Authorize(Roles = "Admin")] [HttpGet] public async Task GetAll([FromQuery] UserFilterRequest filter) => Ok(await _users.GetAllAsync(filter)); [Authorize(Roles = "Admin")] [HttpPatch("{id:int}/role")] public async Task SetRole(int id, [FromBody] UserRole role) { await _users.SetRoleAsync(id, role); return NoContent(); } [Authorize(Roles = "Admin")] [HttpPatch("{id:int}/active")] public async Task SetActive(int id, [FromBody] bool isActive) { await _users.SetActiveAsync(id, isActive); return NoContent(); } }