using Modules.Library.Application.Models.Anime;
using Modules.Library.Database.Database.Models;
using Modules.Library.Database.Database.Models.Anime;
using Modules.Library.Database.Database.Models.CommonProperties;
using Modules.Library.Database.Repositories;

namespace Modules.Library.Database.GatewaysImplementations.Converters;

internal class AnimeSeasonConverter
{
    private readonly CommonPropertiesConverter _commonPropertiesConverter;
    private readonly AnimeEpisodeConverter _animeEpisodeConverter;

    internal AnimeSeasonConverter(CommonPropertiesConverter commonPropertiesConverter)
    {
        _commonPropertiesConverter = commonPropertiesConverter;
        _animeEpisodeConverter = new AnimeEpisodeConverter(commonPropertiesConverter);
    }


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

    /*
    internal async Task<AnimeSeasonBuilder> GetBuilder(AnimeSeason season)
    {
        var seasonBuilder = new AnimeSeasonBuilder();
        seasonBuilder.SetDirector(season.Director)
            .SetOriginCountry(season.OriginCountry)
            .SetNumber(season.Number)
            .SetOrder(season.Order)
            .SetCommonProperties(await _commonPropertiesConverter.GetBuilder(season.CommonProperties))
            .SetExpirationTime(season.ExpirationTime);
        if (season.Deleted) seasonBuilder.Deleted();
        if (season.Completed) seasonBuilder.Completed();
        if (!season.IsTransient()) seasonBuilder.SetId(season.Id);
        foreach (var episode in season.Episodes)
        {
            seasonBuilder.AddEpisode(await _animeEpisodeConverter.GetBuilder(episode));
        }
        return seasonBuilder;
    }
    */
    internal async Task<Application.Models.Anime.Season> Convert(AnimeSeason season)
    {
        var result = new Application.Models.Anime.Season
        {
            Id = season.Id,
            Deleted = season.Deleted,
            Completed = season.Completed,

            CommonProperties = await _commonPropertiesConverter.Convert(season.CommonProperties),
            Number = season.Number,
            Order = season.Order,
            //Variant = season.Variant,
            ExpirationTime = season.ExpirationTime,

            Director = season.Director,
            OriginCountry = season.OriginCountry,
        };
        foreach (var episode in season.Episodes)
        {
            result.Episodes.Add(await _animeEpisodeConverter.Convert(episode));
        }
        return result;
    }

    internal AnimeSeason Convert(Domain.Entities.MediaContent.Items.Anime.AnimeSeason season)
    {
        var dbSeason = new AnimeSeason
        {
            CommonProperties = new CommonProperties
            {
                Names = season.CommonProperties.Names.Select(q => new NameItem
                {
                    Value = q.Value,
                    Type = (NameType)q.Type,
                    LanguageId = q.LanguageId,
                }).ToList(),
                Preview = season.CommonProperties.Preview == null ? null : new MediaInfo
                {
                    //Id = 
                    Type = (MediaInfoType)season.CommonProperties.Preview.Type,
                    ObjectId = season.CommonProperties.Preview.ObjectId,
                    ContentType = season.CommonProperties.Preview.ContentType,
                },
                Descriptions = season.CommonProperties.Descriptions.Select(q => new DescriptionItem
                {
                    IsOriginal = q.IsOriginal,
                    Value = q.Value,
                }).ToList(),
                Genres = season.CommonProperties.Genres.Select(q => new GenreProportionItem
                {
                    GenreId = q.GenreId,
                    Proportion = q.Proportion,
                }).ToList(),
                RelatedContent = season.CommonProperties.RelatedContent.Select(q => new MediaInfo
                {
                    Type = (MediaInfoType)q.Type,
                    ObjectId = q.ObjectId,
                    ContentType = q.ContentType,
                }).ToList(),
                AnnouncementDate = season.CommonProperties.AnnouncementDate,
                EstimatedReleaseDate = season.CommonProperties.EstimatedReleaseDate,
                ReleaseDate = season.CommonProperties.ReleaseDate,
            },
            OriginCountry = season.OriginCountry,
            Director = season.Director,
            Number = season.Number,
            Order = season.Order,
            //Variant = season.Variant,
            Completed = season.Completed,
            Deleted = season.Deleted,
            ExpirationTime = season.ExpirationTime,
        };
        if (!season.IsTransient()) dbSeason.Id = season.Id;
        foreach (var episode in season.Episodes)
        {
            dbSeason.Episodes.Add(_animeEpisodeConverter.Convert(episode));
        }
        return dbSeason;

    }

    internal async Task<Domain.Models.AnimeSeason> ConvertToDomain(AnimeSeason season)
    {
        var result = new Domain.Models.AnimeSeason
        {
            Id = season.Id,
            Deleted = season.Deleted,
            Completed = season.Completed,

            CommonProperties = await _commonPropertiesConverter.ConvertToDomain(season.CommonProperties),
            Number = season.Number,
            Order = season.Order,
            //Variant = season.Variant,
            ExpirationTime = season.ExpirationTime,

            Director = season.Director,
            OriginCountry = season.OriginCountry,
        };
        foreach (var episode in season.Episodes)
        {
            result.Episodes.Add(await _animeEpisodeConverter.ConvertToDomain(episode));
        }
        return result;
    }
}