using Modules.Library.Database.Database.Models.Anime;
using Modules.Library.Database.Database.Models.CommonProperties;
using Modules.Library.Database.Repositories;
using System.Linq;

namespace Modules.Library.Database.GatewaysImplementations.Converters;

internal class AnimeTitleConverter
{
    private readonly LanguageRepository _languageRepository;
    private readonly GenreRepository _genreRepository;
    private readonly CommonPropertiesConverter _commonPropertiesConverter;
    private readonly AnimeSeasonConverter _animeSeasonConverter;
    private readonly AnimeEpisodeConverter _animeEpisodeConverter;

    internal AnimeTitleConverter(LanguageRepository languageRepository, GenreRepository genreRepository)
    {
        _languageRepository = languageRepository;
        _genreRepository = genreRepository;
        _commonPropertiesConverter = new CommonPropertiesConverter(languageRepository, genreRepository);
        _animeSeasonConverter = new AnimeSeasonConverter(_commonPropertiesConverter);
        _animeEpisodeConverter = new AnimeEpisodeConverter(_commonPropertiesConverter);
    }

    internal async Task<Application.Models.Anime.Title> Convert(AnimeTitle title)
    {
        var dto = new Application.Models.Anime.Title
        {
            Id = title.Id,
            Deleted = title.Deleted,
            Rate = null,
            MyRate = null,
            Completed = title.Completed,
            CommonProperties = await _commonPropertiesConverter.Convert(title.CommonProperties),
            ExpirationTime = title.ExpirationTime,
        };
        foreach (var season in title.Items.OfType<AnimeSeason>())
        {
            dto.Items.Add(await _animeSeasonConverter.Convert(season));
        }
        foreach (var episode in title.Items.OfType<AnimeEpisode>())
        {
            dto.Items.Add(await _animeEpisodeConverter.Convert(episode));
        }
        return dto;
    }

    internal async Task<Domain.Entities.MediaContent.Items.Anime.AnimeTitle> ConvertToDomain(AnimeTitle title)
    {
        var dto = new Domain.Models.AnimeTitle
        {
            Id = title.Id,
            Deleted = title.Deleted,
            Completed = title.Completed,
            CommonProperties = await _commonPropertiesConverter.ConvertToDomain(title.CommonProperties),
            ExpirationTime = title.ExpirationTime,
        };
        foreach (var season in title.Items.OfType<AnimeSeason>())
        {
            dto.Items.Add(await _animeSeasonConverter.ConvertToDomain(season));
        }
        foreach (var episode in title.Items.OfType<AnimeEpisode>())
        {
            dto.Items.Add(await _animeEpisodeConverter.ConvertToDomain(episode));
        }
        return Domain.Entities.MediaContent.Items.Anime.AnimeTitle.New(dto);
    }


    

    internal AnimeTitle Convert(Domain.Entities.MediaContent.Items.Anime.AnimeTitle title)
    {
        var dbTitle = new AnimeTitle
        {
            Id = title.Id,
            CommonProperties = _commonPropertiesConverter.Convert(title.CommonProperties),
            Completed = title.Completed,
            Deleted = title.Deleted,
            ExpirationTime = title.ExpirationTime,
        };
        if (!title.IsTransient()) dbTitle.Id = title.Id;
        foreach (var season in title.Items.OfType<Domain.Entities.MediaContent.Items.Anime.AnimeSeason>())
        {
            dbTitle.Items.Add(_animeSeasonConverter.Convert(season));
        }
        foreach (var episode in title.Items.OfType<Domain.Entities.MediaContent.Items.Anime.AnimeEpisode>())
        {
            dbTitle.Items.Add(_animeEpisodeConverter.Convert(episode));
        }
        return dbTitle;

    }
}