using GermanApp.Application.DTOs;
using GermanApp.Domain.Entities;
using GermanApp.Domain.Interfaces;
namespace GermanApp.Application.Services;
///
/// Application service for managing lessons.
/// This is part of the Application layer.
///
public class LessonService
{
private readonly ILessonRepository _lessonRepository;
private readonly ILevelRepository _levelRepository;
public LessonService(ILessonRepository lessonRepository, ILevelRepository levelRepository)
{
_lessonRepository = lessonRepository;
_levelRepository = levelRepository;
}
///
/// Gets all lessons.
///
public async Task> GetAllLessonsAsync(CancellationToken cancellationToken = default)
{
var lessons = await _lessonRepository.GetAllAsync(cancellationToken);
return lessons.Select(l => l.ToDto()).ToList();
}
///
/// Gets all lessons ordered by level and lesson order.
///
public async Task> GetAllOrderedLessonsAsync(CancellationToken cancellationToken = default)
{
var lessons = await _lessonRepository.GetAllOrderedAsync(cancellationToken);
return lessons.Select(l => l.ToDto()).ToList();
}
///
/// Gets a lesson by its ID.
///
public async Task GetLessonByIdAsync(int id, CancellationToken cancellationToken = default)
{
var lesson = await _lessonRepository.GetByIdAsync(id, cancellationToken);
return lesson?.ToDto();
}
///
/// Gets lessons by level ID.
///
public async Task> GetLessonsByLevelAsync(int levelId, CancellationToken cancellationToken = default)
{
var lessons = await _lessonRepository.GetByLevelAsync(levelId, cancellationToken);
return lessons.Select(l => l.ToDto()).ToList();
}
///
/// Gets beginner lessons (A1 and A2 - levels 1 and 2).
///
public async Task> GetBeginnerLessonsAsync(CancellationToken cancellationToken = default)
{
var level1Lessons = await _lessonRepository.GetByLevelAsync(1, cancellationToken);
var level2Lessons = await _lessonRepository.GetByLevelAsync(2, cancellationToken);
var allLessons = level1Lessons.Concat(level2Lessons)
.OrderBy(l => l.LevelId)
.ThenBy(l => l.Order)
.ToList();
return allLessons.Select(l => l.ToDto()).ToList();
}
///
/// Gets advanced lessons (B2 and C1 - levels 4 and 5).
///
public async Task> GetAdvancedLessonsAsync(CancellationToken cancellationToken = default)
{
var level4Lessons = await _lessonRepository.GetByLevelAsync(4, cancellationToken);
var level5Lessons = await _lessonRepository.GetByLevelAsync(5, cancellationToken);
var allLessons = level4Lessons.Concat(level5Lessons)
.OrderBy(l => l.LevelId)
.ThenBy(l => l.Order)
.ToList();
return allLessons.Select(l => l.ToDto()).ToList();
}
///
/// Creates a new lesson.
///
public async Task CreateLessonAsync(CreateLessonDto dto, CancellationToken cancellationToken = default)
{
// Validate that the level exists
var level = await _levelRepository.GetByIdAsync(dto.LevelId, cancellationToken);
if (level == null)
throw new ArgumentException("Level does not exist");
var lesson = dto.ToEntity();
var createdLesson = await _lessonRepository.AddAsync(lesson, cancellationToken);
return createdLesson.ToDto();
}
///
/// Updates an existing lesson.
///
public async Task UpdateLessonAsync(int id, UpdateLessonDto dto, CancellationToken cancellationToken = default)
{
var lesson = await _lessonRepository.GetByIdAsync(id, cancellationToken);
if (lesson == null)
return null;
// Validate that the level exists
var level = await _levelRepository.GetByIdAsync(dto.LevelId, cancellationToken);
if (level == null)
throw new ArgumentException("Level does not exist");
lesson.UpdateFromDto(dto);
await _lessonRepository.UpdateAsync(lesson, cancellationToken);
return lesson.ToDto();
}
///
/// Deletes a lesson by its ID.
///
public async Task DeleteLessonAsync(int id, CancellationToken cancellationToken = default)
{
var lesson = await _lessonRepository.GetByIdAsync(id, cancellationToken);
if (lesson == null)
return false;
await _lessonRepository.DeleteAsync(lesson, cancellationToken);
return true;
}
///
/// Gets the first lesson in a level.
///
public async Task GetFirstLessonInLevelAsync(int levelId, CancellationToken cancellationToken = default)
{
var lesson = await _lessonRepository.GetFirstLessonInLevelAsync(levelId, cancellationToken);
return lesson?.ToDto();
}
///
/// Gets the next lesson after the specified one.
///
public async Task GetNextLessonAsync(int currentLessonId, CancellationToken cancellationToken = default)
{
var lesson = await _lessonRepository.GetNextLessonAsync(currentLessonId, cancellationToken);
return lesson?.ToDto();
}
///
/// Gets lessons that the user can access (based on completion of previous lessons).
///
public async Task> GetAccessibleLessonsAsync(int userId, CancellationToken cancellationToken = default)
{
var lessons = await _lessonRepository.GetAccessibleLessonsAsync(userId, cancellationToken);
return lessons.Select(l => l.ToDto()).ToList();
}
}