MyBookmark/Modules.Library.Domain/EntitiesV1/MediaContent/Items/Anime/AnimeSeason.cs
2024-09-04 23:08:56 +03:00

135 lines
4.8 KiB
C#

using Modules.Library.Domain.EntitiesV0.MediaContent.Items.Anime.ShadowEntities;
namespace Modules.Library.Domain.EntitiesV0.MediaContent.Items.Anime;
public class AnimeSeason : AnimeItem
{
private readonly AnimeTitle _title;
private readonly AnimeSeasonShadow _shadow;
public IReadOnlyCollection<AnimeEpisode> Episodes => _shadow.episodes.Select(q => new AnimeEpisode(_title, this, q)).ToList().AsReadOnly();
public int? Number => _shadow.number;
public string? Director => _shadow.director;
public string? OriginCountry => _shadow.originCountry;
internal AnimeSeason(AnimeTitle title, AnimeSeasonShadow shadow) : base(shadow)
{
_title = title;
_shadow = shadow;
}
protected override CommonProperties.CommonProperties GetCommonProperties() =>
new(_shadow.commonProperties, CheckIsCompleted, CheckIsCompleted, CheckIsCompleted);
public void AddEpisode(AnimeEpisodeType episodeType)
{
StructureAction(() =>
{
var episode = new AnimeEpisodeShadow
{
type = episodeType,
order = GetNewOrder(_shadow.episodes),
number = _shadow.episodes.OfType<AnimeEpisodeShadow>().Select(q => q.number).DefaultIfEmpty(-1).Max() + 1,
};
_shadow.episodes.Add(episode);
});
}
public void AddEpisodeAsVariant(AnimeEpisodeType episodeType, ushort order)
{
StructureAction(() =>
{
if (order < 0 || order > _shadow.episodes.Select(q => q.order).DefaultIfEmpty<ushort>(0).Max())
throw new ArgumentOutOfRangeException(nameof(order));
var episode = new AnimeEpisodeShadow
{
type = episodeType,
order = order,
variant = GetNewVariant(_shadow.episodes, order),
number = _shadow.episodes.FirstOrDefault(q => q.order == order)?.number,
};
_shadow.episodes.Add(episode);
});
}
public void RemoveEpisode(AnimeEpisode episode)
{
StructureAction(() =>
{
episode.SetDeleted();
Sort(_shadow.episodes.Where(q => !q.deleted));
});
}
internal void SetEpisodeOrder(ushort currentOrder, ushort newOrder) =>
SetItemOrder(_shadow.episodes, currentOrder, newOrder);
internal void SetEpisodeVariant(ushort order, ushort currentVariant, ushort newVariant) =>
SetItemVariant(_shadow.episodes.Where(q => q.order == order), currentVariant, newVariant);
internal void SetEpisodeCompleted(ushort order, ushort variant, bool value = true)
{
StructureAction(() =>
{
var episode = _shadow.episodes.FirstOrDefault(q => q.order == order && q.variant == variant) ??
throw new Exception("Episode not found");
episode.completed = value;
});
}
internal void SetEpisodeExpirationTime(ushort order, ushort variant, TimeSpan value)
{
StructureAction(() =>
{
var episode = _shadow.episodes.FirstOrDefault(q => q.order == order && q.variant == variant) ??
throw new Exception("Episode not found");
episode.expirationTime = value;
});
}
private void StructureAction(Action action)
{
action();
CheckIsCompleted();
_title.CheckIsCompleted();
//return new AnimeEpisode(title, this, episodeShadow);
}
public override void SetOrder(ushort order) => SetItemOrder(_title._shadow.items, Order, order);
public override void SetVariant(ushort variant) => throw new NotImplementedException();
public override void SetCompleted()
{
_title.SetSeasonCompleted(Order, Variant, true);
}
public override void SetNotCompleted()
{
throw new NotImplementedException();
}
public override void SetExpirationTime(TimeSpan value)
{
throw new NotImplementedException();
}
internal void SetNumber(int? number) => _shadow.number = number;
internal void SetDirector(string? director) => _shadow.director = director;
internal void SetOriginCountry(string? originCountry) => _shadow.originCountry = originCountry;
internal void CheckIsCompleted()
{
var itemsQuery = Episodes.Where(q => !q.Deleted).AsQueryable();
var unreleasedEpisodesAreExists = itemsQuery
.Any(q => !q.CommonProperties.ReleaseDate.HasValue);
var lastEpisodeReleaseDate = itemsQuery
.OrderByDescending(q => q.CommonProperties.ReleaseDate)
.FirstOrDefault()?.CommonProperties.ReleaseDate;
//return unreleasedEpisodesAreExists || lastEpisodeReleaseDate - DateTime.UtcNow > expirePeriod;
if (unreleasedEpisodesAreExists || lastEpisodeReleaseDate >= DateTime.UtcNow - ExpirationTime) SetNotCompleted();
else SetCompleted();
}
}