/// <summary>
        /// Refresh the <see cref="PlexLibrary"/>, by first deleting all (related) media and the re-adding the media again.
        /// </summary>
        /// <param name="plexLibrary">The <see cref="PlexLibrary"/> to refresh.</param>
        /// <returns></returns>
        private async Task <Result> RefreshPlexMovieLibrary(PlexLibrary plexLibrary)
        {
            if (plexLibrary == null)
            {
                return(ResultExtensions.IsNull(nameof(plexLibrary)));
            }

            // Update the MetaData of this library
            var updateMetaDataResult = plexLibrary.UpdateMetaData();

            if (updateMetaDataResult.IsFailed)
            {
                return(updateMetaDataResult);
            }

            var updateResult = await _mediator.Send(new UpdatePlexLibraryByIdCommand(plexLibrary));

            if (updateResult.IsFailed)
            {
                return(updateResult.ToResult());
            }

            var deleteResult = await _mediator.Send(new DeleteMediaFromPlexLibraryCommand(plexLibrary.Id));

            if (deleteResult.IsFailed)
            {
                return(deleteResult.ToResult());
            }

            var createResult = await _mediator.Send(new CreateUpdateOrDeletePlexMoviesCommand(plexLibrary));

            if (createResult.IsFailed)
            {
                return(createResult.ToResult());
            }

            await _signalRService.SendLibraryProgressUpdate(plexLibrary.Id, plexLibrary.MediaCount, plexLibrary.MediaCount);

            return(Result.Ok());
        }
        /// <summary>
        /// Retrieves all tvshow, season and episode data and stores it in the database.
        /// </summary>
        /// <param name="authToken"></param>
        /// <param name="plexLibrary"></param>
        /// <returns></returns>
        private async Task <Result> RefreshPlexTvShowLibrary(string authToken, PlexLibrary plexLibrary)
        {
            if (plexLibrary == null)
            {
                return(ResultExtensions.IsNull("plexLibrary").LogError());
            }

            if (plexLibrary.Type != PlexMediaType.TvShow)
            {
                return(Result.Fail("PlexLibrary is not of type TvShow").LogError());
            }

            if (plexLibrary.TvShows.Count == 0)
            {
                return(Result.Fail("PlexLibrary does not contain any TvShows and thus cannot request the corresponding media").LogError());
            }

            var result = await _mediator.Send(new GetPlexLibraryByIdWithServerQuery(plexLibrary.Id));

            if (result.IsFailed)
            {
                return(result);
            }

            // Request seasons and episodes for every tv show
            var plexLibraryDb = result.Value;
            var serverUrl     = plexLibraryDb.PlexServer.ServerUrl;
            await _signalRService.SendLibraryProgressUpdate(plexLibrary.Id, 0, 3);

            var timer = new Stopwatch();

            timer.Start();

            var rawSeasonDataResult = await _plexServiceApi.GetAllSeasonsAsync(authToken, serverUrl, plexLibrary.Key);

            if (rawSeasonDataResult.IsFailed)
            {
                return(rawSeasonDataResult.ToResult());
            }

            // Phase 1 of 4: Season data was retrieved successfully.
            await _signalRService.SendLibraryProgressUpdate(plexLibrary.Id, 1, 4);

            var rawEpisodesDataResult = await _plexServiceApi.GetAllEpisodesAsync(authToken, serverUrl, plexLibrary.Key);

            if (rawEpisodesDataResult.IsFailed)
            {
                return(rawEpisodesDataResult.ToResult());
            }

            // Phase 2 of 4: Episode data was retrieved successfully.
            await _signalRService.SendLibraryProgressUpdate(plexLibrary.Id, 2, 4);

            foreach (var plexTvShow in plexLibrary.TvShows)
            {
                plexTvShow.Seasons = rawSeasonDataResult.Value.FindAll(x => x.ParentKey == plexTvShow.Key);
                foreach (var plexTvShowSeason in plexTvShow.Seasons)
                {
                    plexTvShowSeason.PlexLibraryId = plexLibrary.Id;
                    plexTvShowSeason.PlexLibrary   = plexLibrary;
                    plexTvShowSeason.TvShow        = plexTvShow;
                    plexTvShowSeason.Episodes      = rawEpisodesDataResult.Value.FindAll(x => x.ParentKey == plexTvShowSeason.Key);

                    // Set libraryId in each episode
                    plexTvShowSeason.Episodes.ForEach(x => x.PlexLibraryId = plexLibrary.Id);
                    plexTvShowSeason.MediaSize = plexTvShowSeason.Episodes.Sum(x => x.MediaSize);
                }

                plexTvShow.MediaSize = plexTvShow.Seasons.Sum(x => x.MediaSize);
            }

            // Phase 3 of 4: PlexLibrary media data was parsed successfully.
            await _signalRService.SendLibraryProgressUpdate(plexLibrary.Id, 3, 4);

            Log.Debug($"Finished retrieving all media for library {plexLibraryDb.Title} in {timer.Elapsed.TotalSeconds}");
            timer.Restart();

            // Update the MetaData of this library
            var updateMetaDataResult = plexLibrary.UpdateMetaData();

            if (updateMetaDataResult.IsFailed)
            {
                return(updateMetaDataResult);
            }

            var updateResult = await _mediator.Send(new UpdatePlexLibraryByIdCommand(plexLibrary));

            if (updateResult.IsFailed)
            {
                return(updateResult.ToResult());
            }

            var deleteResult = await _mediator.Send(new DeleteMediaFromPlexLibraryCommand(plexLibrary.Id));

            if (deleteResult.IsFailed)
            {
                return(deleteResult.ToResult());
            }

            var createResult = await _mediator.Send(new CreateUpdateOrDeletePlexTvShowsCommand(plexLibrary));

            if (createResult.IsFailed)
            {
                return(createResult.ToResult());
            }

            Log.Debug($"Finished updating all media in the database for library {plexLibraryDb.Title} in {timer.Elapsed.TotalSeconds}");

            // Phase 4 of 4: Database has been successfully updated with new library data.
            await _signalRService.SendLibraryProgressUpdate(plexLibrary.Id, 4, 4);

            return(Result.Ok());
        }