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 virtual 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 virtual 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 virtual async Task GetLessonByIdAsync(int id, CancellationToken cancellationToken = default) { var lesson = await _lessonRepository.GetByIdAsync(id, cancellationToken); return lesson?.ToDto(); } /// /// Gets lessons by level ID. /// public virtual 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 virtual 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 virtual 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 virtual 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 virtual 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 virtual 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 virtual 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 virtual 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 virtual async Task> GetAccessibleLessonsAsync(int userId, CancellationToken cancellationToken = default) { var lessons = await _lessonRepository.GetAccessibleLessonsAsync(userId, cancellationToken); return lessons.Select(l => l.ToDto()).ToList(); } }