using Modules.Library.Database.Database.Models;
using Modules.Library.Database.Database.Models.CommonProperties;
using Modules.Library.Database.Database.Models.Genre;
using Modules.Library.Database.Database.Models.Language;
using Modules.Library.Database.Repositories;

namespace Modules.Library.Database.GatewaysImplementations.Converters;

internal class CommonPropertiesConverter(LanguageRepository languageRepository, GenreRepository genreRepository)
{
    internal async Task<Application.Models.CommonProperties> Convert(CommonProperties commonProperties)
    {
        var commonPropertiesLanguageIds = commonProperties.Names.Select(q => q.LanguageId).ToList();
        commonPropertiesLanguageIds.AddRange(commonProperties.Descriptions.Select(q => q.LanguageId));

        var languages = await languageRepository.GetWhere(q => commonPropertiesLanguageIds.Distinct().Contains(q.Id));
        var genres = await genreRepository.GetWhere(q => commonProperties.Genres.Select(x => x.GenreId).Distinct().Contains(q.Id));

        return new Application.Models.CommonProperties
        {
            Names = commonProperties.Names.Select(q => new Application.Models.NameItem
            {
                Language = Convert(languages.First(x => x.Id == q.LanguageId)),
                Type = (Application.Models.NameType)q.Type,
                Value = q.Value,
            }),
            Preview = commonProperties.Preview == null ? null : new Application.Models.MediaInfo
            {
                ObjectId = commonProperties.Preview.ObjectId,
                Type = (Application.Models.MediaInfoType)commonProperties.Preview.Type,
                //ContentType = commonProperties.Preview.ContentType,
                ContentType = "image/png",

            },
            Descriptions = commonProperties.Descriptions.Select(q => new Application.Models.Description
            {
                Language = Convert(languages.First(x => x.Id == q.LanguageId)),
                IsOriginal = q.IsOriginal,
                Value = q.Value,
            }),
            Genres = commonProperties.Genres.Select(q => new Application.Models.GenreProportion
            {
                //Language = Convert(languages.First(x => x.Id == q.LanguageId)),
                Genre = Convert(genres.First(x => x.Id == q.GenreId)),
                //GenreId = q.GenreId,
                Proportion = q.Proportion,
            }),
            RelatedContent = commonProperties.RelatedContent.Select(q => new Application.Models.MediaInfo
            {
                ObjectId = q.ObjectId,
                Type = (Application.Models.MediaInfoType)q.Type,
            }),
            AnnouncementDate = commonProperties.AnnouncementDate,
            EstimatedReleaseDate = commonProperties.EstimatedReleaseDate,
            ReleaseDate = commonProperties.ReleaseDate,
        };
    }

    private static Application.Models.Language Convert(Language language) => new()
    {
        Id = language.Id,
        CodeIso3 = language.CodeIso3,
        IconId = language.IconId,
        Deleted = language.Deleted,
        Name = language.Name,
    };


    private static Application.Models.Genre Convert(Genre genre) => new()
    {
        Id = genre.Id,
        Deleted = genre.Deleted,
        Name = genre.Name,
    };

    internal CommonProperties Convert(Domain.Entities.MediaContent.CommonProperties.CommonProperties commonProperties)
    {
        var dbCommonProperties = new CommonProperties
        {
            Names = commonProperties.Names.Select(q => new NameItem
            {
                Value = q.Value,
                Type = (NameType)q.Type,
                LanguageId = q.LanguageId,
            }).ToList(),
            Preview = commonProperties.Preview == null ? null : new MediaInfo
            {
                //Id = 
                Type = (MediaInfoType)commonProperties.Preview.Type,
                ObjectId = commonProperties.Preview.ObjectId,
                ContentType = commonProperties.Preview.ContentType,
            },
            Descriptions = commonProperties.Descriptions.Select(q => new DescriptionItem
            {
                IsOriginal = q.IsOriginal,
                LanguageId = q.LanguageId,
                Value = q.Value,
            }).ToList(),
            Genres = commonProperties.Genres.Select(q => new GenreProportionItem
            {
                GenreId = q.GenreId,
                Proportion = q.Proportion,
            }).ToList(),
            RelatedContent = commonProperties.RelatedContent.Select(q => new MediaInfo
            {
                Type = (MediaInfoType)q.Type,
                ObjectId = q.ObjectId,
                ContentType = q.ContentType,
            }).ToList(),
            AnnouncementDate = commonProperties.AnnouncementDate,
            EstimatedReleaseDate = commonProperties.EstimatedReleaseDate,
            ReleaseDate = commonProperties.ReleaseDate,
        };
        return dbCommonProperties;
    }

    internal async Task<Domain.Models.CommonProperties> ConvertToDomain(CommonProperties commonProperties)
    {
        var commonPropertiesLanguageIds = commonProperties.Names.Select(q => q.LanguageId).ToList();
        commonPropertiesLanguageIds.AddRange(commonProperties.Descriptions.Select(q => q.LanguageId));

        var languages = await languageRepository.GetWhere(q => commonPropertiesLanguageIds.Distinct().Contains(q.Id));
        var genres = await genreRepository.GetWhere(q => commonProperties.Genres.Select(q => q.Id).Distinct().Contains(q.Id));

        return new Domain.Models.CommonProperties
        {
            Names = commonProperties.Names.Select(q => new Domain.Models.NameItem
            {
                LanguageId = q.LanguageId,
                Type = (Domain.Entities.MediaContent.CommonProperties.NameType)q.Type,
                Value = q.Value,
            }),
            Preview = commonProperties.Preview == null ? null : new Domain.Models.MediaInfo
            {
                Type = (Domain.Entities.MediaInfoType)commonProperties.Preview.Type,
                ObjectId = commonProperties.Preview.ObjectId,
                ContentType = commonProperties.Preview.ContentType,
            },
            Descriptions = commonProperties.Descriptions.Select(q => new Domain.Models.Description
            {
                LanguageId = q.LanguageId,
                IsOriginal = q.IsOriginal,
                Value = q.Value,
            }),
            Genres = commonProperties.Genres.Select(q => new Domain.Models.GenreProportion
            {
                GenreId = q.GenreId,
                Proportion = q.Proportion,
            }),
            RelatedContent = commonProperties.RelatedContent.Select(q => new Domain.Models.MediaInfo
            {
                Type = (Domain.Entities.MediaInfoType)q.Type,
                ObjectId = q.ObjectId,
                ContentType = q.ContentType,
            }),
            AnnouncementDate = commonProperties.AnnouncementDate,
            EstimatedReleaseDate = commonProperties.EstimatedReleaseDate,
            ReleaseDate = commonProperties.ReleaseDate,
        };
    }
}