using LiteCqrs;
using Microsoft.EntityFrameworkCore;
using TeleWave.Application.Common.Interfaces;
using TeleWave.Application.Common.Models;
using TeleWave.Domain.Programming;

namespace TeleWave.Application.Programming.Groups.Suggest;

public sealed class CreateGroupFromSuggestionCommandHandler(
    IAppDbContext dbContext,
    GroupSuggestionBuilder builder,
    GroupStatsService stats
) : ICommandHandler<CreateGroupFromSuggestionCommand, Result<Guid>>
{
    public async Task<Result<Guid>> Handle(
        CreateGroupFromSuggestionCommand command,
        CancellationToken cancellationToken
    )
    {
        var suggestions = await builder.BuildAsync(cancellationToken);
        var suggestion = suggestions.FirstOrDefault(s => s.Key == command.Key);
        if (suggestion is null)
            return Result.Failure<Guid>(GroupErrors.SuggestionNotFound);

        // Имя — ключ узнаваемости группы, и две «Мультфильм» в списке слота неразличимы. Сравниваем
        // в памяти, а не запросом: групп десятки, зато проверка идёт по тем же правилам, что и
        // пометка «уже есть» в списке предложений, — SQL-регистронезависимость с ней расходится.
        var names = await dbContext.Groups.Select(g => g.Name).ToListAsync(cancellationToken);
        if (
            names.Any(name =>
                string.Equals(
                    name.Trim(),
                    suggestion.Name,
                    StringComparison.CurrentCultureIgnoreCase
                )
            )
        )
            return Result.Failure<Guid>(GroupErrors.SuggestionAlreadyCreated);

        var group = Group.Create(suggestion.Name);
        group.SetFilter(suggestion.Filter?.ToJson());
        foreach (var showId in suggestion.ShowIds)
            group.AddElement(GroupElementKind.Show, showId);

        dbContext.Groups.Add(group);
        await stats.RecomputeAsync(group, cancellationToken);
        return Result.Success(group.Id);
    }
}
