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 quiz questions.
/// This is part of the Presentation layer.
///
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class QuizQuestionsController : ControllerBase
{
private readonly QuizQuestionService _quizQuestionService;
public QuizQuestionsController(QuizQuestionService quizQuestionService)
{
_quizQuestionService = quizQuestionService;
}
///
/// Gets all quiz questions.
///
/// List of all quiz questions
[HttpGet]
public async Task GetAllQuizQuestionsAsync(CancellationToken cancellationToken = default)
{
var questions = await _quizQuestionService.GetAllQuizQuestionsAsync(cancellationToken);
return Ok(questions);
}
///
/// Gets all active quiz questions for a specific quiz.
///
/// The quiz ID
/// List of quiz questions for the specified quiz
[HttpGet("by-quiz/{quizId}")]
public async Task GetQuizQuestionsByQuizAsync(int quizId, CancellationToken cancellationToken = default)
{
var questions = await _quizQuestionService.GetActiveQuizQuestionsByQuizAsync(quizId, cancellationToken);
return Ok(questions);
}
///
/// Gets all active quiz questions for a specific lesson (legacy - uses first quiz).
///
/// The lesson ID
/// List of quiz questions for the specified lesson
[HttpGet("by-lesson/{lessonId}")]
public async Task GetQuizQuestionsByLessonAsync(int lessonId, CancellationToken cancellationToken = default)
{
var questions = await _quizQuestionService.GetActiveQuizQuestionsByLessonAsync(lessonId, cancellationToken);
return Ok(questions);
}
///
/// Gets a specific quiz question by its ID.
///
/// The quiz question ID
/// The quiz question with the specified ID
[HttpGet("{id}")]
public async Task GetQuizQuestionByIdAsync(int id, CancellationToken cancellationToken = default)
{
var question = await _quizQuestionService.GetQuizQuestionByIdAsync(id, cancellationToken);
if (question == null)
return NotFound();
return Ok(question);
}
///
/// Gets a random set of quiz questions for a quiz.
///
/// The quiz ID
/// Number of questions to return
/// List of random quiz questions for the quiz
[HttpGet("random/{quizId}/{count}")]
public async Task GetRandomQuizQuestionsForQuizAsync(int quizId, int count, CancellationToken cancellationToken = default)
{
var questions = await _quizQuestionService.GetRandomQuizQuestionsForQuizAsync(quizId, count, cancellationToken);
return Ok(questions);
}
///
/// Gets a random set of quiz questions for a lesson (legacy - uses first quiz).
///
/// The lesson ID
/// Number of questions to return
/// List of random quiz questions for the lesson
[HttpGet("random/by-lesson/{lessonId}/{count}")]
public async Task GetRandomQuizQuestionsForLessonAsync(int lessonId, int count, CancellationToken cancellationToken = default)
{
var questions = await _quizQuestionService.GetRandomQuizQuestionsForLessonAsync(lessonId, count, cancellationToken);
return Ok(questions);
}
///
/// Gets quiz questions by difficulty level.
///
/// The difficulty level (1-5)
/// List of quiz questions with the specified difficulty
[HttpGet("by-difficulty/{difficulty}")]
public async Task GetQuizQuestionsByDifficultyAsync(int difficulty, CancellationToken cancellationToken = default)
{
var questions = await _quizQuestionService.GetQuizQuestionsByDifficultyAsync(difficulty, cancellationToken);
return Ok(questions);
}
///
/// Gets quiz questions by type.
///
/// The question type
/// List of quiz questions with the specified type
[HttpGet("by-type/{type}")]
public async Task GetQuizQuestionsByTypeAsync(QuestionType type, CancellationToken cancellationToken = default)
{
var questions = await _quizQuestionService.GetQuizQuestionsByTypeAsync(type, cancellationToken);
return Ok(questions);
}
///
/// Creates a new quiz question.
///
/// The quiz question data (requires QuizId)
/// The created quiz question
[HttpPost]
[Authorize(Roles = "Admin")]
public async Task CreateQuizQuestionAsync(CreateQuizQuestionDto dto, CancellationToken cancellationToken = default)
{
var question = await _quizQuestionService.CreateQuizQuestionAsync(dto, cancellationToken);
return CreatedAtAction(nameof(GetQuizQuestionByIdAsync), new { id = question.Id }, question);
}
///
/// Updates an existing quiz question.
///
/// The quiz question ID
/// The updated quiz question data
/// The updated quiz question
[HttpPut("{id}")]
[Authorize(Roles = "Admin")]
public async Task UpdateQuizQuestionAsync(int id, UpdateQuizQuestionDto dto, CancellationToken cancellationToken = default)
{
var question = await _quizQuestionService.UpdateQuizQuestionAsync(id, dto, cancellationToken);
if (question == null)
return NotFound();
return Ok(question);
}
///
/// Deletes a quiz question by its ID.
///
/// The quiz question ID
/// No content on success
[HttpDelete("{id}")]
[Authorize(Roles = "Admin")]
public async Task DeleteQuizQuestionAsync(int id, CancellationToken cancellationToken = default)
{
var result = await _quizQuestionService.DeleteQuizQuestionAsync(id, cancellationToken);
if (!result)
return NotFound();
return NoContent();
}
///
/// Gets quiz options for a specific question.
///
/// The question ID
/// List of quiz options for the question
[HttpGet("options/{questionId}")]
public async Task GetQuizOptionsByQuestionAsync(int questionId, CancellationToken cancellationToken = default)
{
var options = await _quizQuestionService.GetQuizOptionsByQuestionAsync(questionId, cancellationToken);
return Ok(options);
}
///
/// Gets the correct option for a question.
///
/// The question ID
/// The correct option for the question
[HttpGet("correct-option/{questionId}")]
public async Task GetCorrectOptionAsync(int questionId, CancellationToken cancellationToken = default)
{
var option = await _quizQuestionService.GetCorrectOptionAsync(questionId, cancellationToken);
if (option == null)
return NotFound();
return Ok(option);
}
///
/// Gets all correct options for a question (for MultipleSelect type).
///
/// The question ID
/// List of correct options for the question
[HttpGet("correct-options/{questionId}")]
public async Task GetCorrectOptionsAsync(int questionId, CancellationToken cancellationToken = default)
{
var options = await _quizQuestionService.GetCorrectOptionsAsync(questionId, cancellationToken);
return Ok(options);
}
///
/// Creates a new quiz option for a question.
///
/// The question ID
/// The quiz option data
/// The created quiz option
[HttpPost("options/{questionId}")]
[Authorize(Roles = "Admin")]
public async Task CreateQuizOptionAsync(int questionId, CreateQuizOptionDto dto, CancellationToken cancellationToken = default)
{
var option = await _quizQuestionService.CreateQuizOptionAsync(questionId, dto, cancellationToken);
return CreatedAtAction(nameof(GetQuizOptionsByQuestionAsync), new { questionId }, option);
}
///
/// Updates an existing quiz option.
///
/// The quiz option ID
/// The updated quiz option data
/// The updated quiz option
[HttpPut("options/{id}")]
[Authorize(Roles = "Admin")]
public async Task UpdateQuizOptionAsync(int id, UpdateQuizOptionDto dto, CancellationToken cancellationToken = default)
{
var option = await _quizQuestionService.UpdateQuizOptionAsync(id, dto, cancellationToken);
if (option == null)
return NotFound();
return Ok(option);
}
///
/// Deletes a quiz option by its ID.
///
/// The quiz option ID
/// No content on success
[HttpDelete("options/{id}")]
[Authorize(Roles = "Admin")]
public async Task DeleteQuizOptionAsync(int id, CancellationToken cancellationToken = default)
{
var result = await _quizQuestionService.DeleteQuizOptionAsync(id, cancellationToken);
if (!result)
return NotFound();
return NoContent();
}
///
/// Submits quiz answers and returns the result.
///
/// The user ID
/// The quiz answers submission (requires QuizId)
/// The quiz result
[HttpPost("submit/{userId}")]
[Authorize]
public async Task SubmitQuizAnswersAsync(int userId, SubmitQuizAnswersDto dto, CancellationToken cancellationToken = default)
{
// Convert legacy DTO to new format
var newDto = new SubmitQuizDto(dto.QuizId, dto.Answers);
var result = await _quizQuestionService.SubmitQuizAnswersForQuizAsync(userId, newDto, cancellationToken);
return Ok(result);
}
///
/// Gets the number of quiz questions for a lesson.
///
/// The lesson ID
/// The count of quiz questions for the lesson
[HttpGet("count/{lessonId}")]
public async Task GetQuizQuestionCountForLessonAsync(int lessonId, CancellationToken cancellationToken = default)
{
var count = await _quizQuestionService.GetQuizQuestionCountForLessonAsync(lessonId, cancellationToken);
return Ok(new { lessonId, count });
}
///
/// Gets the difficulty distribution for a lesson.
///
/// The lesson ID
/// The difficulty distribution for the lesson
[HttpGet("difficulty-distribution/{lessonId}")]
public async Task GetDifficultyDistributionAsync(int lessonId, CancellationToken cancellationToken = default)
{
var distribution = await _quizQuestionService.GetDifficultyDistributionAsync(lessonId, cancellationToken);
return Ok(distribution);
}
///
/// Gets the type distribution for a lesson.
///
/// The lesson ID
/// The type distribution for the lesson
[HttpGet("type-distribution/{lessonId}")]
public async Task GetTypeDistributionAsync(int lessonId, CancellationToken cancellationToken = default)
{
var distribution = await _quizQuestionService.GetTypeDistributionAsync(lessonId, cancellationToken);
return Ok(distribution);
}
}