using GermanApp.Domain.Entities;
using GermanApp.Domain.Interfaces;
using GermanApp.Infrastructure.Data.DbContext;
using Microsoft.EntityFrameworkCore;
namespace GermanApp.Infrastructure.Data.Repositories;
///
/// Entity Framework Core implementation of IQuizQuestionRepository.
/// This is part of the Infrastructure layer.
///
public class QuizQuestionRepository : IQuizQuestionRepository
{
private readonly AppDbContext _context;
public QuizQuestionRepository(AppDbContext context)
{
_context = context;
}
public async Task GetByIdAsync(int id, CancellationToken cancellationToken = default)
{
return await _context.QuizQuestions
.Include(q => q.Lesson)
.Include(q => q.Options.OrderBy(o => o.Order))
.FirstOrDefaultAsync(q => q.Id == id, cancellationToken);
}
public async Task> GetAllAsync(CancellationToken cancellationToken = default)
{
return await _context.QuizQuestions
.Include(q => q.Lesson)
.Include(q => q.Options)
.AsNoTracking()
.ToListAsync(cancellationToken);
}
public async Task AddAsync(QuizQuestion entity, CancellationToken cancellationToken = default)
{
await _context.QuizQuestions.AddAsync(entity, cancellationToken);
await _context.SaveChangesAsync(cancellationToken);
return entity;
}
public async Task UpdateAsync(QuizQuestion entity, CancellationToken cancellationToken = default)
{
_context.QuizQuestions.Update(entity);
await _context.SaveChangesAsync(cancellationToken);
}
public async Task DeleteAsync(QuizQuestion entity, CancellationToken cancellationToken = default)
{
_context.QuizQuestions.Remove(entity);
await _context.SaveChangesAsync(cancellationToken);
}
public async Task ExistsAsync(int id, CancellationToken cancellationToken = default)
{
return await _context.QuizQuestions
.AnyAsync(q => q.Id == id, cancellationToken);
}
public async Task> GetByLessonAsync(int lessonId, CancellationToken cancellationToken = default)
{
return await _context.QuizQuestions
.Include(q => q.Lesson)
.Include(q => q.Options.OrderBy(o => o.Order))
.Where(q => q.LessonId == lessonId)
.OrderBy(q => q.Order)
.AsNoTracking()
.ToListAsync(cancellationToken);
}
public async Task> GetAllOrderedAsync(CancellationToken cancellationToken = default)
{
return await _context.QuizQuestions
.Include(q => q.Lesson)
.Include(q => q.Options.OrderBy(o => o.Order))
.OrderBy(q => q.Lesson.Order)
.ThenBy(q => q.Order)
.AsNoTracking()
.ToListAsync(cancellationToken);
}
public async Task> GetActiveByLessonAsync(int lessonId, CancellationToken cancellationToken = default)
{
return await _context.QuizQuestions
.Include(q => q.Lesson)
.Include(q => q.Options.OrderBy(o => o.Order))
.Where(q => q.LessonId == lessonId && q.IsActive)
.OrderBy(q => q.Order)
.AsNoTracking()
.ToListAsync(cancellationToken);
}
public async Task> GetRandomQuestionsForLessonAsync(int lessonId, int count, CancellationToken cancellationToken = default)
{
return await _context.QuizQuestions
.Include(q => q.Lesson)
.Include(q => q.Options.OrderBy(o => o.Order))
.Where(q => q.LessonId == lessonId && q.IsActive)
.OrderBy(q => Guid.NewGuid()) // Random ordering
.Take(count)
.AsNoTracking()
.ToListAsync(cancellationToken);
}
public async Task> GetByDifficultyAsync(int difficulty, CancellationToken cancellationToken = default)
{
return await _context.QuizQuestions
.Include(q => q.Lesson)
.Include(q => q.Options)
.Where(q => q.Difficulty == difficulty)
.OrderBy(q => q.Order)
.AsNoTracking()
.ToListAsync(cancellationToken);
}
public async Task> GetByTypeAsync(QuestionType type, CancellationToken cancellationToken = default)
{
return await _context.QuizQuestions
.Include(q => q.Lesson)
.Include(q => q.Options)
.Where(q => q.Type == type)
.OrderBy(q => q.Order)
.AsNoTracking()
.ToListAsync(cancellationToken);
}
public async Task OrderExistsInLessonAsync(int lessonId, int order, int? excludeId = null, CancellationToken cancellationToken = default)
{
var query = _context.QuizQuestions
.Where(q => q.LessonId == lessonId && q.Order == order);
if (excludeId.HasValue)
{
query = query.Where(q => q.Id != excludeId.Value);
}
return await query.AnyAsync(cancellationToken);
}
}