MyBookmark/Modules.Library.Domain/EntitiesV0/MediaContent/CommonProperties/CommonProperties.cs
2024-09-04 23:08:56 +03:00

241 lines
9.5 KiB
C#

using Modules.Library.Domain.EntitiesV0.MediaContent.CommonProperties.ShadowEntities;
namespace Modules.Library.Domain.EntitiesV0.MediaContent.CommonProperties;
public class CommonProperties : Entity
{
private readonly CommonPropertiesShadow _shadow;
public IReadOnlyCollection<NameItem> Names => _shadow.names.AsReadOnly();
public MediaInfo? Preview => _shadow.preview;
public IReadOnlyCollection<DescriptionItem> Descriptions => _shadow.descriptions.AsReadOnly();
public IReadOnlyCollection<GenreProportionItem> Genres => _shadow.genres.AsReadOnly();
public IReadOnlyCollection<MediaInfo> RelatedContent => _shadow.relatedContent.AsReadOnly();
public DateTimeOffset? AnnouncementDate => _shadow.announcementDate;
internal Action? AfterAnnouncementDateSet;
public DateTimeOffset? EstimatedReleaseDate => _shadow.estimatedReleaseDate;
internal Action? AfterEstimatedReleaseDateSet;
public DateTimeOffset? ReleaseDate => _shadow.releaseDate;
internal Action? AfterReleaseDateSet;
public override bool Deleted => false;
internal CommonProperties(CommonPropertiesShadow shadow, Action? afterAnnouncementDateSet, Action? afterEstimatedReleaseDateSet, Action? afterReleaseDateSet)
{
_shadow = shadow;
AfterAnnouncementDateSet = afterAnnouncementDateSet;
AfterEstimatedReleaseDateSet = afterEstimatedReleaseDateSet;
AfterReleaseDateSet = afterReleaseDateSet;
}
#region Name
internal void AddNameOriginal(string languageId, string value)
{
if (_shadow.names.Any(q => q.Type == NameType.Original)) throw new Exception("Original name is already exist.");
var name = new NameItem(languageId, NameType.Original, value);
AddName(name, value);
}
internal void AddNameOriginalInAnotherLanguage(string languageId, string value)
{
if (languageId == _shadow.names.Single(q => q.Type == NameType.Original).LanguageId)
throw new Exception("Language must not match original name language");
if (_shadow.names.Any(q => q.Type == NameType.OriginalInAnotherLanguage && q.LanguageId == languageId))
throw new Exception("Name in following language is already exist.");
var name = new NameItem(languageId, NameType.OriginalInAnotherLanguage);
AddName(name, value);
}
internal void AddNameTranslation(string languageId, string value)
{
var name = new NameItem(languageId, NameType.Translation);
AddName(name, value);
}
internal void AddNameAbbreviation(string languageId, string value)
{
var name = new NameItem(languageId, NameType.Abbreviation);
AddName(name, value);
}
private void AddName(NameItem nameItem, string value)
{
_shadow.names.Add(nameItem);
SetNameValue(nameItem, value);
}
internal void RemoveName(string nameId)
{
var name = GetName(nameId);
if (name.Type == NameType.Original) throw new Exception($"Unable to remove original name");
name.SetDeleted();
//_names.Remove(name);
}
internal void SetNameValue(string nameId, string value) => SetNameValue(GetName(nameId), value);
private void SetNameValue(NameItem nameItem, string value)
{
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentNullException(nameof(value));
if (nameItem.Type != NameType.Original && _shadow.names.Any(q => q.LanguageId == nameItem.LanguageId && q.Value == value))
throw new Exception("Name item with in same language with same value is already exists");
nameItem.SetValue(value);
}
private NameItem GetName(string nameId) => _shadow.names.FirstOrDefault(q => q.Id == nameId) ??
throw new Exception($"Name with id [{nameId}] is not found");
#endregion
internal void SetPreview(string url, MediaInfoType type)
{
if (string.IsNullOrWhiteSpace(url)) throw new ArgumentNullException(nameof(url));
_shadow.preview ??= new MediaInfo(url, type);
_shadow.preview.SetUrl(url);
}
internal void DeletePreview()
{
_shadow.preview = null;
}
#region Description
internal void AddOriginalDescription(string languageId, string value)
{
if (_shadow.descriptions.Any(q => q.IsOriginal)) throw new Exception("Original description is already exist.");
var description = new DescriptionItem(languageId, true);
_shadow.descriptions.Add(description);
SetDescriptionValue(description, value);
}
internal void AddNotOriginalDescription(string languageId, string value)
{
var description = new DescriptionItem(languageId, false);
_shadow.descriptions.Add(description);
SetDescriptionValue(description, value);
}
internal void RemoveDescription(string descriptionId)
{
var description = GetDescription(descriptionId);
if (description.IsOriginal) throw new Exception($"Unable to remove original description");
//_descriptions.Remove(name);
description.SetDeleted();
}
internal void SetDescriptionValue(string descriptionId, string value)
{
var name = GetDescription(descriptionId);
SetDescriptionValue(name, value);
}
private void SetDescriptionValue(DescriptionItem descriptionItem, string value)
{
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentNullException(nameof(value));
if (!descriptionItem.IsOriginal && _shadow.descriptions.Any(q => q.LanguageId == descriptionItem.LanguageId && q.Value == value))
throw new Exception("Descriptoin item with with same value is already exists");
descriptionItem.SetValue(value);
}
private DescriptionItem GetDescription(string descriptionId)
{
return _shadow.descriptions.FirstOrDefault(q => q.Id == descriptionId) ??
throw new Exception($"Description with id [{descriptionId}] is not found");
}
#endregion
#region Genre
internal void AddGenre(string genreId, decimal? proportion = null)
{
if (_shadow.genres.Any(q => q.GenreId == genreId)) throw new Exception("Genre is already in the list");
var genreProportionItem = new GenreProportionItem(genreId);
_shadow.genres.Add(genreProportionItem);
if (proportion.HasValue) genreProportionItem.SetProportion(proportion);
}
internal void SetGenreProportion(string genreProportionItemId, decimal? value = null)
{
var genreProportionItem = GetGenreProportionItem(genreProportionItemId);
genreProportionItem.SetProportion(value);
}
internal void RemoveGenre(string genreProportionItemId)
{
var genreProportionItem = GetGenreProportionItem(genreProportionItemId);
//_genres.Remove(genreProportionItem);
genreProportionItem.SetDeleted();
}
private GenreProportionItem GetGenreProportionItem(string genreProportionItemId)
{
return _shadow.genres.FirstOrDefault(q => q.Id == genreProportionItemId) ??
throw new Exception($"Genre proportion item with id [{genreProportionItemId}] is not found");
}
#endregion
#region RelatedContent
internal void AddRelatedContent(string url, MediaInfoType type)
{
if (string.IsNullOrWhiteSpace(url)) throw new ArgumentNullException(nameof(url));
CheckIfCanAddOrEdit(url, type);
_shadow.relatedContent.Add(new MediaInfo(url, type));
}
internal void EditRelatedContent(string relatedContentId, string url, MediaInfoType type)
{
var relatedContent = GetRelatedContent(relatedContentId);
CheckIfCanAddOrEdit(url, type);
relatedContent.SetUrl(url);
relatedContent.SetType(type);
}
internal void RemoveRelatedContent(string relatedContentId)
{
var relatedContent = GetRelatedContent(relatedContentId);
//_relatedContent.Remove(relatedContent);
relatedContent.SetDeleted();
}
private void CheckIfCanAddOrEdit(string url, MediaInfoType type)
{
if (_shadow.relatedContent.Any(q => q.Url == url && q.Type == type))
throw new Exception("Related content with same url and same type is already exists");
}
private MediaInfo GetRelatedContent(string relatedContentId)
{
return _shadow.relatedContent.FirstOrDefault(q => q.Id == relatedContentId) ??
throw new Exception($"Related content with id [{relatedContentId}] is not found");
}
#endregion
internal void SetAnnouncementDate(DateTimeOffset value)
{
if (value == default) throw new ArgumentNullException(nameof(value));
_shadow.announcementDate = value;
AfterAnnouncementDateSet?.Invoke();
}
internal void SetEstimatedReleaseDate(DateTimeOffset value)
{
if (value == default) throw new ArgumentNullException(nameof(value));
if (_shadow.announcementDate.HasValue && value <= _shadow.announcementDate.Value)
throw new Exception("Estimated release date can not be less or equal to announcement date");
_shadow.estimatedReleaseDate = value;
AfterEstimatedReleaseDateSet?.Invoke();
}
internal void SetReleaseDate(DateTimeOffset value)
{
if (value == default) throw new ArgumentNullException(nameof(value));
if (_shadow.announcementDate.HasValue && value <= _shadow.announcementDate.Value)
throw new Exception("Release date can not be less or equal to announcement date");
_shadow.releaseDate = value;
AfterReleaseDateSet?.Invoke();
}
internal override void SetDeleted() { }
}