using BukiVedi.Shared.Entities;
using BukiVedi.Shared.Models;
using MongoDB.Driver;

namespace BukiVedi.Shared.Services.Mappers
{
    public class BookEntityMapper
    {
        public static async Task<IEnumerable<BookInfo>> Map(IEnumerable<BookEntity> books, OperationContext context)
        {
            var booksIds = books.Select(x => x.Id).ToList();
            var tags_list = (await Tables.UserTag.Get(Filters.Tags.ByBooks(booksIds, context.OperationInitiator.Id)));
            var tags = new Dictionary<string, List<TagInfo>>();
            foreach (var t in tags_list)
            {
                if (tags.TryGetValue(t.BookId, out var list)) { list.Add(new TagInfo { Id = t.Id, Name = t.Name }); }
                else
                {
                    tags.Add(t.BookId,
                        new List<TagInfo>
                        {
                            new TagInfo { Id = t.Id, Name = t.Name }
                        });
                }
            }

            var favorites = (await Tables.FavoriteBooks.Get(Filters.FavoriteBooks.ByBooks(booksIds, context.OperationInitiator.Id)))?.Select(f => f.BookId)?.ToHashSet();
            var blocked = (await Tables.DisgustingBooks.Get(Filters.DisgustingBooks.ByBooks(booksIds, context.OperationInitiator.Id)))?.Select(f => f.BookId)?.ToHashSet();

            return books.Select(book =>
                new BookInfo
                {
                    Authors = book.Authors.Select(a => new AuthorInfo { Id = a.Id, Name = a.Name }).ToArray(),
                    Description = book.Description,
                    Format = book.Format,
                    Id = book.Id,
                    Genres = new GenreInfo[1] { new GenreInfo { Id = book.Genre.Id, Name = book.Genre.Code } },
                    Title = book.Title,
                    Year = book.Year,
                    Tags = tags.ContainsKey(book.Id) ? tags[book.Id] : null!,
                    IsFavorite = favorites?.Contains(book.Id) ?? false,
                    IsBlocked = blocked?.Contains(book.Id) ?? false,
                    Series = string.Empty,
                    Subseries = string.Empty,
                });
        }
    }
}
