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

namespace TeleWave.Application.Library.DeleteShow;

public sealed class DeleteShowCommandHandler(
    IAppDbContext dbContext,
    GroupMembershipCleaner groupCleaner
) : ICommandHandler<DeleteShowCommand, Result>
{
    public async Task<Result> Handle(DeleteShowCommand command, CancellationToken cancellationToken)
    {
        var show = await dbContext.Shows.FirstOrDefaultAsync(
            s => s.Id == command.ShowId,
            cancellationToken
        );
        if (show is null)
            return Result.Failure(ShowErrors.NotFound);

        // Уже сгенерированный эфир ссылается на шоу без внешнего ключа: удали его — и зритель
        // получит запись без названия, а раздача упрётся в удалённые каскадом серии. Прошедшие
        // записи не держим: они лишь теряют название в EPG, а иначе шоу было бы не удалить никогда.
        var onAir = await dbContext.ScheduleEntries.AnyAsync(
            e => e.ShowId == command.ShowId && e.EndsAtUtc > DateTimeOffset.UtcNow,
            cancellationToken
        );
        if (onAir)
            return Result.Failure(ShowErrors.InFutureSchedule);

        // Позиции коллекций уходят каскадом БД, позиции групп — вручную: ссылка группы полиморфна.
        await groupCleaner.RemoveElementAsync(
            GroupElementKind.Show,
            command.ShowId,
            cancellationToken
        );

        dbContext.Shows.Remove(show);
        return Result.Success();
    }
}
