namespace Francesco.Recipes.World.Repositories.Instruction { using Francesco.Recipes.World.Data; using Francesco.Recipes.World.Models.BackendModels.Instruction; using Francesco.Recipes.World.Repositories.Recipe; using Microsoft.EntityFrameworkCore; public class InstructionRepository : IInstructionRepository { private readonly FrancescosRecipesWorldDbContext _context; private readonly IRecipeRepository _recipeRepository; public InstructionRepository(FrancescosRecipesWorldDbContext context, IRecipeRepository recipeRepository) { _recipeRepository = recipeRepository; _context = context; } public async Task GetInstructionAsync(Guid instructionId) { var instruction = await _context.Instructions.FindAsync(instructionId); return instruction ?? throw new InvalidDataException($"Instruction {instructionId} not found."); } public async Task CreateInstructionToRecipeAsync(Guid recipeId, string description, int number) { var recipe = await _recipeRepository.GetRecipeAsync(recipeId); if (string.IsNullOrWhiteSpace(description)) { throw new ArgumentException("Description cannot be empty", nameof(description)); } if (number <= 0) { throw new ArgumentOutOfRangeException(nameof(number), "Number must be greater than 0."); } var newInstruction = new Instruction { Id = Guid.NewGuid(), Description = description, Number = number, Recipe = recipe, }; _context.Instructions.Add(newInstruction); await _context.SaveChangesAsync(); return newInstruction; } public async Task RemoveInstructionFromRecipeAsync(Guid recipeId, Guid instructionId) { var recipe = await _recipeRepository.GetRecipeAsync(recipeId); if (recipe.Instructions == null || !recipe.Instructions.Any()) { await _context.Entry(recipe) .Collection(r => r.Instructions) .LoadAsync(); } var instructionToRemove = recipe.Instructions?.FirstOrDefault(i => i.Id == instructionId); if (instructionToRemove != null) { recipe.Instructions?.Remove(instructionToRemove); await _context.SaveChangesAsync(); } } public async Task> GetInstructionsByRecipeIdAsync(Guid recipeId) { return await _context.Instructions .Include(i => i.Recipe) .Where(i => i.Recipe.Id == recipeId) .ToListAsync(); } public async Task GetInstructionWithRecipeAsync(Guid instructionId) { var instruction = await _context.Instructions .Include(i => i.Recipe) .ThenInclude(r => r.Instructions) .FirstOrDefaultAsync(i => i.Id == instructionId); if (instruction == null) { throw new InvalidDataException($"Instruction with ID {instructionId} not found."); } if (instruction.Recipe == null) { throw new InvalidDataException($"The Recipe for Instruction with ID {instructionId} is not loaded or does not exist."); } return instruction; } public async Task SwapInstructionOrderAsync(Instruction a, Instruction b) { if (a == null) { throw new ArgumentNullException(nameof(a), "Instruction 'a' cannot be null."); } if (b == null) { throw new ArgumentNullException(nameof(b), "Instruction 'b' cannot be null."); } var temp = a.Number; a.Number = b.Number; b.Number = temp; await _context.SaveChangesAsync(); } } }