using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using API.Data;
using API.Entities.Person;
using API.Extensions;
namespace API.Services;
public interface IPersonService
{
///
/// Adds src as an alias to dst, this is a destructive operation
///
/// Remaining person
/// Merged person
/// The entities passed as arguments **must** include all relations
///
Task MergePeopleAsync(Person dst, Person src);
///
/// Adds the alias to the person, requires that the aliases are not shared with anyone else
///
/// This method does NOT commit changes
///
///
///
Task UpdatePersonAliasesAsync(Person person, IList aliases);
}
public class PersonService(IUnitOfWork unitOfWork): IPersonService
{
public async Task MergePeopleAsync(Person dst, Person src)
{
if (dst.Id == src.Id) return;
if (string.IsNullOrWhiteSpace(dst.Description) && !string.IsNullOrWhiteSpace(src.Description))
{
dst.Description = src.Description;
}
if (dst.MalId == 0 && src.MalId != 0)
{
dst.MalId = src.MalId;
}
if (dst.AniListId == 0 && src.AniListId != 0)
{
dst.AniListId = src.AniListId;
}
if (dst.HardcoverId == null && src.HardcoverId != null)
{
dst.HardcoverId = src.HardcoverId;
}
if (dst.Asin == null && src.Asin != null)
{
dst.Asin = src.Asin;
}
if (dst.CoverImage == null && src.CoverImage != null)
{
dst.CoverImage = src.CoverImage;
}
foreach (var chapter in src.ChapterPeople)
{
dst.ChapterPeople.Add(new ChapterPeople
{
Role = chapter.Role,
ChapterId = chapter.ChapterId,
Person = dst,
KavitaPlusConnection = chapter.KavitaPlusConnection,
OrderWeight = chapter.OrderWeight,
});
}
foreach (var series in src.SeriesMetadataPeople)
{
dst.SeriesMetadataPeople.Add(new SeriesMetadataPeople
{
SeriesMetadataId = series.SeriesMetadataId,
Role = series.Role,
Person = dst,
KavitaPlusConnection = series.KavitaPlusConnection,
OrderWeight = series.OrderWeight,
});
}
dst.Aliases.Add(new PersonAlias
{
Alias = src.Name,
NormalizedAlias = src.NormalizedName,
});
foreach (var alias in src.Aliases)
{
dst.Aliases.Add(alias);
}
unitOfWork.PersonRepository.Remove(src);
unitOfWork.PersonRepository.Update(dst);
await unitOfWork.CommitAsync();
}
public async Task UpdatePersonAliasesAsync(Person person, IList aliases)
{
var normalizedAliases = aliases
.Select(a => a.ToNormalized().Trim())
.Where(a => !string.IsNullOrWhiteSpace(a))
.Where(a => a != person.NormalizedName)
.ToList();
if (normalizedAliases.Count == 0)
{
person.Aliases = [];
return true;
}
var others = await unitOfWork.PersonRepository.GetPeopleByNames(normalizedAliases);
others = others.Where(p => p.Id != person.Id).ToList();
if (others.Count != 0) return false;
person.Aliases = aliases.Select(a => new PersonAlias
{
Alias = a.Trim(),
NormalizedAlias = a.Trim().ToNormalized()
}).ToList();
return true;
}
}