using ErsatzTV.Core;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Errors;
using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Infrastructure.Data;
using ErsatzTV.Infrastructure.Extensions;
using Microsoft.EntityFrameworkCore;

namespace ErsatzTV.Application.ChannelTemplates;

public class DeleteChannelTemplateHandler(
    IDbContextFactory<TvContext> dbContextFactory,
    IConfigElementRepository configElementRepository)
    : IRequestHandler<DeleteChannelTemplate, Either<BaseError, Unit>>
{
    public async Task<Either<BaseError, Unit>> Handle(DeleteChannelTemplate request, CancellationToken cancellationToken)
    {
        await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
        Option<ChannelTemplate> maybeTemplate = await dbContext.ChannelTemplates
            .SelectOneAsync(t => t.Id, t => t.Id == request.ChannelTemplateId, cancellationToken);
        foreach (ChannelTemplate template in maybeTemplate)
        {
            if (template.IsSystem)
            {
                return BaseError.New("System templates cannot be deleted.");
            }

            int? defaultTemplateId =
                await ChannelTemplateDefault.GetDefaultTemplateId(configElementRepository, cancellationToken);
            if (defaultTemplateId == template.Id)
            {
                return BaseError.New("Default channel template cannot be deleted.");
            }

            dbContext.ChannelTemplates.Remove(template);
            await dbContext.SaveChangesAsync(cancellationToken);
            return Unit.Default;
        }

        return new NotFoundError($"ChannelTemplate {request.ChannelTemplateId} does not exist.");
    }
}
