using AutoMapper; using GameIdeas.Shared.Constants; using GameIdeas.Shared.Dto; using GameIdeas.Shared.Exceptions; using GameIdeas.Shared.Model; using GameIdeas.WebAPI.Context; using Microsoft.EntityFrameworkCore; namespace GameIdeas.WebAPI.Services.Games; public class GameWriteService(GameIdeasContext context, IMapper mapper) : IGameWriteService { public async Task CreateGame(GameDetailDto gameDto) { var gameToCreate = mapper.Map(gameDto); await HandlePublisherCreation(gameDto.Publisher); await HandleDeveloperCreation(gameDto.Developer); await context.Games.AddAsync(gameToCreate); await context.SaveChangesAsync(); await HandlePlatformsCreation(gameDto.Platforms, gameToCreate.Id); await HandlePropertiesCreation(gameDto.Properties, gameToCreate.Id); await HandleTagsCreation(gameDto.Tags, gameToCreate.Id); await context.SaveChangesAsync(); return mapper.Map(gameToCreate); } public async Task UpdateGame(GameDetailDto gameDto) { if (await context.Games.CountAsync(g => g.Id == gameDto.Id) == 0) { throw new NotFoundException($"[{typeof(Game).FullName}] with ID {gameDto.Id} has not been found in context"); } var gameToUpdate = mapper.Map(gameDto); await HandlePublisherCreation(gameDto.Publisher); await HandleDeveloperCreation(gameDto.Developer); await HandlePlatformsCreation(gameDto.Platforms, gameToUpdate.Id); await HandlePropertiesCreation(gameDto.Properties, gameToUpdate.Id); await HandleTagsCreation(gameDto.Tags, gameToUpdate.Id); context.Games.Update(gameToUpdate); await context.SaveChangesAsync(); return mapper.Map(gameToUpdate); } public async Task DeleteGame(int gameId) { var gameToRemove = await context.Games .FirstOrDefaultAsync(g => g.Id == gameId) ?? throw new NotFoundException($"[{typeof(Game).FullName}] with ID {gameId} has not been found in context"); context.Games.Remove(gameToRemove); return await context.SaveChangesAsync() != 0; } private async Task HandlePlatformsCreation(IEnumerable? categoriesToCreate, int gameId) { if (categoriesToCreate != null) { var gps = mapper.Map>(categoriesToCreate); foreach (var gp in gps) { gp.GameId = gameId; } context.Platforms.AttachRange(gps.Select(gp => gp.Platform)); await context.GamePlatforms.AddRangeAsync(gps); } } private async Task HandlePropertiesCreation(IEnumerable? categoriesToCreate, int gameId) { if (categoriesToCreate != null) { var gps = mapper.Map>(categoriesToCreate); foreach (var gp in gps) { gp.GameId = gameId; } context.Properties.AttachRange(gps.Select(gp => gp.Property)); await context.GameProperties.AddRangeAsync(gps); } } private async Task HandleTagsCreation(IEnumerable? categoriesToCreate, int gameId) { if (categoriesToCreate != null) { var gts = mapper.Map>(categoriesToCreate); foreach (var gt in gts) { gt.GameId = gameId; } context.Tags.AttachRange(gts.Select(gt => gt.Tag)); await context.GameTags.AddRangeAsync(gts); } } private async Task HandlePublisherCreation(PublisherDto? categoriesToCreate) { if (categoriesToCreate != null) { var pub = mapper.Map(categoriesToCreate); context.Publishers.Attach(pub); await context.Publishers.AddAsync(pub); } } private async Task HandleDeveloperCreation(DeveloperDto? categoriesToCreate) { if (categoriesToCreate != null) { var dev = mapper.Map(categoriesToCreate); context.Developers.Attach(dev); await context.Developers.AddAsync(dev); } } }