using GermanApp.Application.DTOs;
using GermanApp.Application.Services;
using GermanApp.Domain.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace GermanApp.Presentation.Controllers;
///
/// API controller for managing quizzes.
/// This is part of the Presentation layer.
///
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class QuizzesController : ControllerBase
{
private readonly QuizService _quizService;
private readonly QuizQuestionService _quizQuestionService;
public QuizzesController(
QuizService quizService,
QuizQuestionService quizQuestionService)
{
_quizService = quizService;
_quizQuestionService = quizQuestionService;
}
///
/// Gets all quizzes.
///
/// List of all quizzes
[HttpGet]
public async Task GetAllQuizzesAsync(CancellationToken cancellationToken = default)
{
var quizzes = await _quizService.GetAllQuizzesAsync(cancellationToken);
return Ok(quizzes);
}
///
/// Gets all quizzes as list items (summary).
///
/// List of quiz summary items
[HttpGet("list")]
public async Task GetAllQuizListItemsAsync(CancellationToken cancellationToken = default)
{
var quizzes = await _quizService.GetAllQuizListItemsAsync(cancellationToken);
return Ok(quizzes);
}
///
/// Gets a specific quiz by its ID.
///
/// The quiz ID
/// The quiz with the specified ID
[HttpGet("{id}")]
public async Task GetQuizByIdAsync(int id, CancellationToken cancellationToken = default)
{
var quiz = await _quizService.GetQuizByIdAsync(id, cancellationToken);
if (quiz == null)
return NotFound();
return Ok(quiz);
}
///
/// Gets a quiz with its questions by ID.
///
/// The quiz ID
/// The quiz with questions
[HttpGet("{id}/with-questions")]
public async Task GetQuizWithQuestionsAsync(int id, CancellationToken cancellationToken = default)
{
var quiz = await _quizService.GetQuizWithQuestionsAsync(id, cancellationToken);
if (quiz == null)
return NotFound();
return Ok(quiz);
}
///
/// Gets all quizzes for a specific lesson.
///
/// The lesson ID
/// List of quizzes for the specified lesson
[HttpGet("by-lesson/{lessonId}")]
public async Task GetQuizzesByLessonAsync(int lessonId, CancellationToken cancellationToken = default)
{
var quizzes = await _quizService.GetQuizzesByLessonAsync(lessonId, cancellationToken);
return Ok(quizzes);
}
///
/// Gets active quizzes for a specific lesson.
///
/// The lesson ID
/// List of active quizzes for the specified lesson
[HttpGet("active/by-lesson/{lessonId}")]
public async Task GetActiveQuizzesByLessonAsync(int lessonId, CancellationToken cancellationToken = default)
{
var quizzes = await _quizService.GetActiveQuizzesByLessonAsync(lessonId, cancellationToken);
return Ok(quizzes);
}
///
/// Gets the first quiz for a lesson.
///
/// The lesson ID
/// The first quiz for the lesson
[HttpGet("first/by-lesson/{lessonId}")]
public async Task GetFirstQuizByLessonAsync(int lessonId, CancellationToken cancellationToken = default)
{
var quiz = await _quizService.GetFirstQuizByLessonAsync(lessonId, cancellationToken);
if (quiz == null)
return NotFound();
return Ok(quiz);
}
///
/// Gets all active quizzes.
///
/// List of active quizzes
[HttpGet("active")]
public async Task GetActiveQuizzesAsync(CancellationToken cancellationToken = default)
{
var quizzes = await _quizService.GetActiveQuizzesAsync(cancellationToken);
return Ok(quizzes);
}
///
/// Creates a new quiz.
///
/// The quiz data
/// The created quiz
[HttpPost]
[Authorize(Roles = "Admin")]
public async Task CreateQuizAsync(CreateQuizDto dto, CancellationToken cancellationToken = default)
{
var quiz = await _quizService.CreateQuizAsync(dto, cancellationToken);
return CreatedAtAction(nameof(GetQuizByIdAsync), new { id = quiz.Id }, quiz);
}
///
/// Updates an existing quiz.
///
/// The quiz ID
/// The updated quiz data
/// The updated quiz
[HttpPut("{id}")]
[Authorize(Roles = "Admin")]
public async Task UpdateQuizAsync(int id, UpdateQuizDto dto, CancellationToken cancellationToken = default)
{
var quiz = await _quizService.UpdateQuizAsync(id, dto, cancellationToken);
if (quiz == null)
return NotFound();
return Ok(quiz);
}
///
/// Deletes a quiz by its ID.
///
/// The quiz ID
/// No content on success
[HttpDelete("{id}")]
[Authorize(Roles = "Admin")]
public async Task DeleteQuizAsync(int id, CancellationToken cancellationToken = default)
{
var result = await _quizService.DeleteQuizAsync(id, cancellationToken);
if (!result)
return NotFound();
return NoContent();
}
///
/// Activates a quiz.
///
/// The quiz ID
/// The activated quiz
[HttpPost("{id}/activate")]
[Authorize(Roles = "Admin")]
public async Task ActivateQuizAsync(int id, CancellationToken cancellationToken = default)
{
var quiz = await _quizService.ActivateQuizAsync(id, cancellationToken);
if (quiz == null)
return NotFound();
return Ok(quiz);
}
///
/// Deactivates a quiz.
///
/// The quiz ID
/// The deactivated quiz
[HttpPost("{id}/deactivate")]
[Authorize(Roles = "Admin")]
public async Task DeactivateQuizAsync(int id, CancellationToken cancellationToken = default)
{
var quiz = await _quizService.DeactivateQuizAsync(id, cancellationToken);
if (quiz == null)
return NotFound();
return Ok(quiz);
}
///
/// Checks if a quiz exists by ID.
///
/// The quiz ID
/// True if the quiz exists
[HttpGet("exists/{id}")]
public async Task ExistsAsync(int id, CancellationToken cancellationToken = default)
{
var exists = await _quizService.ExistsAsync(id, cancellationToken);
return Ok(new { exists });
}
///
/// Checks if a quiz exists for a lesson.
///
/// The lesson ID
/// True if a quiz exists for the lesson
[HttpGet("exists/by-lesson/{lessonId}")]
public async Task ExistsByLessonAsync(int lessonId, CancellationToken cancellationToken = default)
{
var exists = await _quizService.ExistsByLessonAsync(lessonId, cancellationToken);
return Ok(new { lessonId, exists });
}
///
/// Gets the total number of quizzes.
///
/// The total count of quizzes
[HttpGet("count")]
public async Task GetTotalQuizCountAsync(CancellationToken cancellationToken = default)
{
var count = await _quizService.GetTotalQuizCountAsync(cancellationToken);
return Ok(new { count });
}
///
/// Gets the number of quizzes for a lesson.
///
/// The lesson ID
/// The count of quizzes for the lesson
[HttpGet("count/by-lesson/{lessonId}")]
public async Task GetQuizCountByLessonAsync(int lessonId, CancellationToken cancellationToken = default)
{
var count = await _quizService.GetQuizCountByLessonAsync(lessonId, cancellationToken);
return Ok(new { lessonId, count });
}
///
/// Gets quizzes by passing score range.
///
/// Minimum passing score
/// Maximum passing score
/// List of quizzes in the score range
[HttpGet("by-passing-score/{minScore}/{maxScore}")]
public async Task GetQuizzesByPassingScoreRangeAsync(int minScore, int maxScore, CancellationToken cancellationToken = default)
{
var quizzes = await _quizService.GetQuizzesByPassingScoreRangeAsync(minScore, maxScore, cancellationToken);
return Ok(quizzes);
}
///
/// Gets quiz questions for a specific quiz.
///
/// The quiz ID
/// List of quiz questions for the quiz
[HttpGet("{quizId}/questions")]
public async Task GetQuizQuestionsByQuizAsync(int quizId, CancellationToken cancellationToken = default)
{
var questions = await _quizQuestionService.GetQuizQuestionsByQuizAsync(quizId, cancellationToken);
return Ok(questions);
}
///
/// Gets active quiz questions for a specific quiz.
///
/// The quiz ID
/// List of active quiz questions for the quiz
[HttpGet("{quizId}/questions/active")]
public async Task GetActiveQuizQuestionsByQuizAsync(int quizId, CancellationToken cancellationToken = default)
{
var questions = await _quizQuestionService.GetActiveQuizQuestionsByQuizAsync(quizId, cancellationToken);
return Ok(questions);
}
///
/// Gets random quiz questions for a quiz.
///
/// The quiz ID
/// Number of questions to return
/// List of random quiz questions
[HttpGet("{quizId}/questions/random/{count}")]
public async Task GetRandomQuizQuestionsForQuizAsync(int quizId, int count, CancellationToken cancellationToken = default)
{
var questions = await _quizQuestionService.GetRandomQuizQuestionsForQuizAsync(quizId, count, cancellationToken);
return Ok(questions);
}
///
/// Submits quiz answers and returns the result.
///
/// The user ID
/// The quiz ID
/// The quiz answers submission
/// The quiz result
[HttpPost("submit/{userId}/{quizId}")]
[Authorize]
public async Task SubmitQuizAnswersAsync(int userId, int quizId, SubmitQuizDto dto, CancellationToken cancellationToken = default)
{
// Update the submission to use the correct quizId
var submission = new SubmitQuizDto(quizId, dto.Answers);
var result = await _quizQuestionService.SubmitQuizAnswersForQuizAsync(userId, submission, cancellationToken);
return Ok(result);
}
///
/// Gets the total points for a quiz.
///
/// The quiz ID
/// The total points for the quiz
[HttpGet("{quizId}/total-points")]
public async Task GetTotalPointsForQuizAsync(int quizId, CancellationToken cancellationToken = default)
{
var points = await _quizQuestionService.GetTotalPointsForQuizAsync(quizId, cancellationToken);
return Ok(new { quizId, points });
}
}