using LiteCqrs;
using Microsoft.EntityFrameworkCore;
using TeleWave.Application.Common.Interfaces;

namespace TeleWave.Application.Library.Collections.Suggest;

public sealed class SuggestCollectionsQueryHandler(
    IAppDbContext dbContext,
    CollectionSuggestionBuilder builder
) : IQueryHandler<SuggestCollectionsQuery, IReadOnlyList<CollectionSuggestionDto>>
{
    public async Task<IReadOnlyList<CollectionSuggestionDto>> Handle(
        SuggestCollectionsQuery query,
        CancellationToken cancellationToken
    )
    {
        var suggestions = await builder.BuildAsync(cancellationToken);
        if (suggestions.Count == 0)
            return [];

        var names = await dbContext
            .Collections.AsNoTracking()
            .Select(c => c.Name)
            .ToListAsync(cancellationToken);
        var existing = names
            .Select(n => n.Trim())
            .ToHashSet(StringComparer.CurrentCultureIgnoreCase);

        // У дополнения имя — это имя самой коллекции, и совпадение с ней ничего не значит: такое
        // предложение и живёт ровно потому, что франшиза уже собрана.
        bool AlreadyCreated(CollectionSuggestion s) =>
            s.CollectionId is null && existing.Contains(s.Name);

        return
        [
            .. suggestions.Select(s => new CollectionSuggestionDto(
                s.Key,
                s.Source,
                s.Name,
                s.Parts,
                AlreadyCreated(s),
                s.CollectionId
            )),
        ];
    }
}
