using ErsatzTV.Core;
using ErsatzTV.Core.Api.ChannelTemplates;
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 SetDefaultChannelTemplateHandler(
    IDbContextFactory<TvContext> dbContextFactory,
    IConfigElementRepository configElementRepository)
    : IRequestHandler<SetDefaultChannelTemplate, Either<BaseError, ChannelTemplateResponseModel>>
{
    public async Task<Either<BaseError, ChannelTemplateResponseModel>> Handle(
        SetDefaultChannelTemplate request,
        CancellationToken cancellationToken)
    {
        await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
        Option<ChannelTemplate> maybeTemplate = await dbContext.ChannelTemplates
            .AsNoTracking()
            .SelectOneAsync(t => t.Id, t => t.Id == request.ChannelTemplateId, cancellationToken);
        foreach (ChannelTemplate template in maybeTemplate)
        {
            await configElementRepository.Upsert(
                ConfigElementKey.ChannelTemplatesDefaultTemplateId,
                template.Id,
                cancellationToken);
            return ChannelTemplateMapper.ProjectToResponseModel(template, template.Id);
        }

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