using GermanApp.Application.DTOs; using GermanApp.Application.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace GermanApp.Presentation.Controllers; /// /// API controller for managing CEFR levels. /// This is part of the Presentation layer. /// [ApiController] [Route("api/[controller]")] [Authorize] public class LevelsController : ControllerBase { private readonly LevelService _levelService; public LevelsController(LevelService levelService) { _levelService = levelService; } /// /// Gets all CEFR levels ordered by their sort order. /// /// List of all levels [HttpGet] [AllowAnonymous] public async Task>> GetAllLevelsAsync(CancellationToken cancellationToken = default) { var levels = await _levelService.GetAllLevelsAsync(cancellationToken); return Ok(levels); } /// /// Gets a specific level by its ID. /// /// The level ID /// The level with the specified ID [HttpGet("{id}")] [AllowAnonymous] public async Task> GetLevelByIdAsync(int id, CancellationToken cancellationToken = default) { var level = await _levelService.GetLevelByIdAsync(id, cancellationToken); if (level == null) return NotFound(); return Ok(level); } /// /// Gets a level by its code (e.g., "A1", "B2"). /// /// The level code /// The level with the specified code [HttpGet("by-code/{code}")] [AllowAnonymous] public async Task> GetLevelByCodeAsync(string code, CancellationToken cancellationToken = default) { var level = await _levelService.GetLevelByCodeAsync(code, cancellationToken); if (level == null) return NotFound(); return Ok(level); } /// /// Creates a new CEFR level. /// /// The level data /// The created level [HttpPost] [Authorize(Roles = "Admin")] public async Task> CreateLevelAsync(CreateLevelDto dto, CancellationToken cancellationToken = default) { var level = await _levelService.CreateLevelAsync(dto, cancellationToken); return CreatedAtAction(nameof(GetLevelByIdAsync), new { id = level.Id }, level); } /// /// Updates an existing CEFR level. /// /// The level ID /// The updated level data /// The updated level [HttpPut("{id}")] [Authorize(Roles = "Admin")] public async Task> UpdateLevelAsync(int id, UpdateLevelDto dto, CancellationToken cancellationToken = default) { var level = await _levelService.UpdateLevelAsync(id, dto, cancellationToken); if (level == null) return NotFound(); return Ok(level); } /// /// Deletes a CEFR level by its ID. /// /// The level ID /// No content on success [HttpDelete("{id}")] [Authorize(Roles = "Admin")] public async Task DeleteLevelAsync(int id, CancellationToken cancellationToken = default) { var result = await _levelService.DeleteLevelAsync(id, cancellationToken); if (!result) return NotFound(); return NoContent(); } /// /// Gets the first level (lowest order number) - typically A1. /// /// The first level [HttpGet("first")] [AllowAnonymous] public async Task> GetFirstLevelAsync(CancellationToken cancellationToken = default) { var level = await _levelService.GetFirstLevelAsync(cancellationToken); if (level == null) return NotFound(); return Ok(level); } /// /// Gets the next level after the specified one. /// /// The current level ID /// The next level [HttpGet("next/{currentLevelId}")] [AllowAnonymous] public async Task> GetNextLevelAsync(int currentLevelId, CancellationToken cancellationToken = default) { var level = await _levelService.GetNextLevelAsync(currentLevelId, cancellationToken); if (level == null) return NotFound(); return Ok(level); } }