using System.Threading; using System.Threading.Tasks; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; using LanguageExt; namespace ErsatzTV.Application.MediaCollections.Commands { public class AddMovieToSimpleMediaCollectionHandler : MediatR.IRequestHandler> { private readonly IMediaCollectionRepository _mediaCollectionRepository; private readonly IMovieRepository _movieRepository; public AddMovieToSimpleMediaCollectionHandler( IMediaCollectionRepository mediaCollectionRepository, IMovieRepository movieRepository) { _mediaCollectionRepository = mediaCollectionRepository; _movieRepository = movieRepository; } public Task> Handle( AddMovieToSimpleMediaCollection request, CancellationToken cancellationToken) => Validate(request) .MapT(ApplyAddMoviesRequest) .Bind(v => v.ToEitherAsync()); private async Task ApplyAddMoviesRequest(RequestParameters parameters) { parameters.Collection.Movies.Add(parameters.MovieToAdd); await _mediaCollectionRepository.Update(parameters.Collection); return Unit.Default; } private async Task> Validate(AddMovieToSimpleMediaCollection request) => (await SimpleMediaCollectionMustExist(request), await ValidateMovies(request)) .Apply( (simpleMediaCollectionToUpdate, movieToAdd) => new RequestParameters(simpleMediaCollectionToUpdate, movieToAdd)); private Task> SimpleMediaCollectionMustExist( AddMovieToSimpleMediaCollection updateSimpleMediaCollection) => _mediaCollectionRepository.GetSimpleMediaCollectionWithItems(updateSimpleMediaCollection.MediaCollectionId) .Map(v => v.ToValidation("SimpleMediaCollection does not exist.")); private Task> ValidateMovies( AddMovieToSimpleMediaCollection request) => LoadMovie(request) .Map(v => v.ToValidation("MovieMediaItem does not exist")); private Task> LoadMovie(AddMovieToSimpleMediaCollection request) => _movieRepository.GetMovie(request.MovieId); private record RequestParameters(SimpleMediaCollection Collection, MovieMediaItem MovieToAdd); } }