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

namespace TeleWave.Application.Programming.Groups.DeleteGroup;

public sealed class DeleteGroupCommandHandler(IAppDbContext dbContext)
    : ICommandHandler<DeleteGroupCommand, Result>
{
    public async Task<Result> Handle(
        DeleteGroupCommand command,
        CancellationToken cancellationToken
    )
    {
        var group = await dbContext.Groups.FirstOrDefaultAsync(
            g => g.Id == command.GroupId,
            cancellationToken
        );
        if (group is null)
            return Result.Failure(GroupErrors.NotFound);

        // Слот и врезка стыка держат группу внешним ключом с Restrict — без этой проверки удаление
        // упало бы исключением БД вместо управляемой ошибки. Запасная группа шаблона внешнего ключа
        // не имеет, и там висячая ссылка проявилась бы только в эфире: генератор молча остался бы
        // без замены для пустого слота.
        var used =
            await dbContext.Slots.AnyAsync(s => s.GroupId == group.Id, cancellationToken)
            || await dbContext.JunctionElements.AnyAsync(
                e => e.GroupId == group.Id,
                cancellationToken
            )
            || await dbContext.ScheduleTemplates.AnyAsync(
                t => t.FallbackGroupId == group.Id,
                cancellationToken
            );
        if (used)
            return Result.Failure(GroupErrors.InUse);

        dbContext.Groups.Remove(group);
        return Result.Success();
    }
}
