using GamificationService.Exceptions.Services.Instruction; using GamificationService.Models.Database; using GamificationService.Models.DTO; using GamificationService.Models.Messages.Instructions; using GamificationService.Services.Instructions; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; namespace GamificationService.Controllers; [ApiController] [Route("api/[controller]")] [Authorize(Policy = "User")] public class InstructionController : ControllerBase { private readonly IInstructionService _instructionService; private readonly UserManager _userManager; private readonly ILogger _logger; public InstructionController(IInstructionService instructionService, UserManager userManager, ILogger logger) { _instructionService = instructionService; _userManager = userManager; _logger = logger; } /// /// Create a new instruction. /// /// The instruction model. /// which was created /// Returns the created instruction [HttpPost] [Authorize(Policy = "Admin")] public async Task CreateInstruction([FromBody] CreateInstructionRequest model) { var instruction = await _instructionService.CreateInstruction(model); return Ok(instruction); } /// /// Update an existing instruction. /// /// The instruction model. Id must match the object which is being updated. /// /// /// If the instruction is not found [HttpPut] [Authorize(Policy = "Admin")] public async Task UpdateInstruction([FromBody] UpdateInstructionRequest model) { var instruction = await _instructionService.UpdateInstructionById(model); return Ok(instruction); } /// /// Delete an existing instruction. /// /// The ID of the instruction to delete. /// /// /// If the instruction is not found [HttpDelete] [Authorize(Policy = "Admin")] public async Task DeleteInstruction(long id) { try { return Ok(await _instructionService.DeleteInstructionById(id)); } catch (InstructionNotFoundException) { return NotFound(); } } /// /// Retrieve all instructions for the authenticated user. /// /// A list of for the user. /// Returns the list of all instructions [HttpGet("all")] public async Task GetAllInstructions() { string username = User.Claims.First(c => c.Type == "username").Value; long userId = (await _userManager.FindByNameAsync(username))!.Id; return Ok(_instructionService.GetAllInstructions(userId)); } /// /// Retrieve all completed instructions for the authenticated user. /// /// A list of that are completed for the user. /// Returns the list of completed instructions [HttpGet("completed")] public async Task GetCompletedInstructions() { string username = User.Claims.First(c => c.Type == "username").Value; long userId = (await _userManager.FindByNameAsync(username))!.Id; return Ok(_instructionService.GetCompletedInstructions(userId)); } /// /// Retrieve all unfinished instructions for the authenticated user. /// /// A list of that are unfinished for the user. /// Returns the list of unfinished instructions [HttpGet("unfinished")] public async Task GetUnfinishedInstructions() { string username = User.Claims.First(c => c.Type == "username").Value; long userId = (await _userManager.FindByNameAsync(username))!.Id; return Ok(_instructionService.GetUnfinishedInstructions(userId)); } /// /// Retrieve instructions by category ID for the authenticated user. /// /// The ID of the category to filter instructions. /// A list of for the specified category. /// Returns the list of instructions for the specified category /// If the category is not found [HttpGet("category/{id}")] public async Task GetInstructionsByCategoryId(long id) { try { string username = User.Claims.First(c => c.Type == "username").Value; long userId = (await _userManager.FindByNameAsync(username))!.Id; return Ok(_instructionService.GetInstructionsByCategoryId(userId, id)); } catch (CategoryNotFoundException) { return NotFound(); } } /// /// Retrieve a specific instruction by its ID for the authenticated user. /// /// The ID of the instruction to retrieve. /// for the specified instruction. /// Returns the instruction with the specified ID /// If the instruction is not found [HttpGet("{id}")] public async Task GetInstructionById(long id) { try { string username = User.Claims.First(c => c.Type == "username").Value; long userId = (await _userManager.FindByNameAsync(username))!.Id; return Ok(_instructionService.GetInstructionById(userId, id)); } catch(InstructionNotFoundException) { return NotFound(); } } }