using Microsoft.EntityFrameworkCore; using Modules.Library.Database.Database; using Modules.Library.Database.Database.Models; using Modules.Library.Database.Database.Models.Anime; using Modules.Library.Database.Database.Models.CommonProperties; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Linq.Expressions; namespace Modules.Library.Database.Repositories; //public class AnimeTitleRepository(LibraryDbContext context) : RepositoryBase(context) public class AnimeTitleRepository(LibraryDbContext context) { private readonly LibraryDbContext _context = context; internal async Task AddAsync(AnimeTitle animeTitle) { _context.AnimeTitles.Add(animeTitle); await _context.SaveChangesAsync(); return animeTitle.Id; } private IQueryable QueryFullIncludes() => _context.AnimeTitles .Include(q => q.CommonProperties).ThenInclude(q => q.Names) .Include(q => q.CommonProperties).ThenInclude(q => q.Descriptions) .Include(q => q.CommonProperties).ThenInclude(q => q.RelatedContent) .Include(q => q.CommonProperties).ThenInclude(q => q.Genres) .Include(q => q.CommonProperties).ThenInclude(q => q.Preview) .Include(q => q.Items).ThenInclude(q => q.CommonProperties).ThenInclude(q => q.Names) .Include(q => q.Items).ThenInclude(q => q.CommonProperties).ThenInclude(q => q.Descriptions) .Include(q => q.Items).ThenInclude(q => q.CommonProperties).ThenInclude(q => q.RelatedContent) .Include(q => q.Items).ThenInclude(q => q.CommonProperties).ThenInclude(q => q.Genres) .Include(q => q.Items).ThenInclude(q => q.CommonProperties).ThenInclude(q => q.Preview) .AsQueryable(); internal async Task> GetAllAsync() => await QueryFullIncludes().ToListAsync(); internal async Task GetFirstWhere(Expression> predicate) => await QueryFullIncludes().FirstAsync(predicate); internal async Task UpdateAsync(AnimeTitle animeTitle) { var dbTitle = await GetFirstWhere(q => q.Id == animeTitle.Id); SyncCommonProperties(dbTitle.CommonProperties, animeTitle.CommonProperties); //NOT UPDATE INNER ITEMS dbTitle.ExpirationTime = animeTitle.ExpirationTime; dbTitle.Completed = animeTitle.Completed; await _context.SaveChangesAsync(); } private void SyncCommonProperties(CommonProperties db, CommonProperties newCommonProperties) { db.Preview = newCommonProperties.Preview; db.AnnouncementDate = newCommonProperties.AnnouncementDate; db.EstimatedReleaseDate = newCommonProperties.EstimatedReleaseDate; db.ReleaseDate = newCommonProperties.ReleaseDate; //sync names var deleteNames = db.Names.Except(newCommonProperties.Names, new NameComparer()).ToList(); var addNames = newCommonProperties.Names.Except(db.Names, new NameComparer()); if (deleteNames.Any()) { foreach (var name in deleteNames) { db.Names.Remove(db.Names.First(q => q.Id == name.Id)); } } if (addNames.Any()) { db.Names.AddRange(addNames); } //if (updateNames.Any()) //{ // foreach (var name in updateNames) // { // var existingName = db.Names.First(q => q.Id == name.Id); // existingName.Value = name.Value; // existingName.Type = name.Type; // existingName.LanguageId = name.LanguageId; // } //} //sync descriptions var deleteDescriptions = db.Descriptions.Except(newCommonProperties.Descriptions, new DescriptionComparer()).ToList(); var addDescriptions = newCommonProperties.Descriptions.Except(db.Descriptions, new DescriptionComparer()); //var updateDescriptions = db.Descriptions.Except(deleteDescriptions.Union(addDescriptions)); if (deleteDescriptions.Any()) { foreach (var description in deleteDescriptions) { db.Descriptions.Remove(db.Descriptions.First(q => q.Id == description.Id)); } } if (addDescriptions.Any()) { db.Descriptions.AddRange(addDescriptions); } //if (updateDescriptions.Any()) //{ // foreach (var description in updateDescriptions) // { // var existingDescription = db.Descriptions.First(q => q.Id == description.Id); // existingDescription.LanguageId = description.LanguageId; // existingDescription.IsOriginal = description.IsOriginal; // existingDescription.Value = description.Value; // } //} //sync genres var deleteGenres = db.Genres.Except(newCommonProperties.Genres, new GenreComparer()).ToList(); var addGenres = newCommonProperties.Genres.Except(db.Genres, new GenreComparer()); var updateGenres = newCommonProperties.Genres.Where(q => db.Genres.Any(x => x.GenreId == q.GenreId && x.Proportion != q.Proportion)); if (deleteGenres.Any()) { foreach (var genre in deleteGenres) { db.Genres.Remove(db.Genres.First(q => q.Id == genre.Id)); } } if (addGenres.Any()) { db.Genres.AddRange(addGenres); } if (updateGenres.Any()) { foreach (var genre in updateGenres) { var dbGenre = db.Genres.First(q => q.GenreId == genre.GenreId); dbGenre.Proportion = genre.Proportion; } } //sync related content var deleteRelatedContent = db.RelatedContent.Except(newCommonProperties.RelatedContent, new MediaInfoComparer()).ToList(); var addRelatedContent = newCommonProperties.RelatedContent.Except(db.RelatedContent, new MediaInfoComparer()); //var updateRelatedContent = db.RelatedContent.Except(deleteRelatedContent.Union(addRelatedContent)); if (deleteRelatedContent.Any()) { foreach (var relatedContent in deleteRelatedContent) { db.RelatedContent.Remove(db.RelatedContent.First(q => q.Id == relatedContent.Id)); } } if (addRelatedContent.Any()) { db.RelatedContent.AddRange(addRelatedContent); } //if (updateRelatedContent.Any()) //{ // foreach (var relatedContent in updateRelatedContent) // { // var existingRelatedContent = db.RelatedContent.First(q => q.Id == relatedContent.Id); // existingRelatedContent.Url = relatedContent.Url; // existingRelatedContent.Type = relatedContent.Type; // existingRelatedContent.ContentType = relatedContent.ContentType; // } //} } private class NameComparer : IEqualityComparer { public bool Equals(NameItem? x, NameItem? y) { return x != null && y != null && x.LanguageId == y.LanguageId && x.Type == y.Type && x.Value == y.Value; } public int GetHashCode([DisallowNull] NameItem obj) { return HashCode.Combine(obj.LanguageId.GetHashCode(), obj.Type.GetHashCode(), obj.Value.GetHashCode()); } } private class DescriptionComparer : IEqualityComparer { public bool Equals(DescriptionItem? x, DescriptionItem? y) { return x != null && y != null && x.LanguageId == y.LanguageId && x.IsOriginal == y.IsOriginal && x.Value == y.Value; } public int GetHashCode([DisallowNull] DescriptionItem obj) { return HashCode.Combine(obj.LanguageId.GetHashCode(), obj.IsOriginal.GetHashCode(), obj.Value.GetHashCode()); } } private class GenreComparer : IEqualityComparer { public bool Equals(GenreProportionItem? x, GenreProportionItem? y) { return x != null && y != null && x.GenreId == y.GenreId; } public int GetHashCode([DisallowNull] GenreProportionItem obj) { return obj.GenreId.GetHashCode(); } } private class MediaInfoComparer : IEqualityComparer { public bool Equals(MediaInfo? x, MediaInfo? y) { return x != null && y != null && x.Url == y.Url && x.Type == y.Type && x.ContentType == y.ContentType; } public int GetHashCode([DisallowNull] MediaInfo obj) { return HashCode.Combine(obj.Url.GetHashCode(), obj.Type.GetHashCode(), obj.ContentType.GetHashCode()); } } //protected override async Task SoftDeleteAsync(AnimeTitle entity) //{ // entity.Deleted = true; // return await UpdateAsync(entity); //} /* public async Task AddAsync(Domain.Entities.MediaContent.Items.Anime.AnimeTitle entity, IUser user) => await AddAsync(ToDbConverter.Title(entity)); public Task AnyWhere(Expression> predicate) { var p = predicate. } public Task DeleteAsync(Domain.Entities.MediaContent.Items.Anime.AnimeTitle entity, IUser user) { throw new NotImplementedException(); } public Task GetByIdAsync(string id) { throw new NotImplementedException(); } public Task GetByIdOrDefaultAsync(string id) { throw new NotImplementedException(); } public Task GetFirstOrDefaultWhere(Expression> predicate) { throw new NotImplementedException(); } public Task GetFirstWhere(Expression> predicate) { throw new NotImplementedException(); } public Task> GetRangeByIdsAsync(List ids) { throw new NotImplementedException(); } public Task> GetWhere(Expression> predicate) { throw new NotImplementedException(); } public Task UpdateAsync(Domain.Entities.MediaContent.Items.Anime.AnimeTitle entity, IUser user) { throw new NotImplementedException(); } Task> Application.Gateways.IRepository.GetAllAsync() { throw new NotImplementedException(); } */ }