using ErsatzTV.Core; using ErsatzTV.Core.Domain.Scheduling; using ErsatzTV.Infrastructure.Data; using Microsoft.EntityFrameworkCore; namespace ErsatzTV.Application.Scheduling; public class CreateDecoTemplateHandler(IDbContextFactory dbContextFactory) : IRequestHandler> { public async Task> Handle( CreateDecoTemplate request, CancellationToken cancellationToken) { await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken); Validation validation = await Validate(dbContext, request); return await validation.Apply(profile => PersistDecoTemplate(dbContext, profile)); } private static async Task PersistDecoTemplate(TvContext dbContext, DecoTemplate decoTemplate) { await dbContext.DecoTemplates.AddAsync(decoTemplate); await dbContext.SaveChangesAsync(); await dbContext.Entry(decoTemplate).Reference(dt => dt.DecoTemplateGroup).LoadAsync(); return Mapper.ProjectToViewModel(decoTemplate); } private static async Task> Validate( TvContext dbContext, CreateDecoTemplate request) { Validation decoTemplateGroupValidation = await ValidateDecoTemplateGroupExists(dbContext, request); Validation nameValidation = await ValidateDecoTemplateName(dbContext, request); return (decoTemplateGroupValidation, nameValidation).Apply((_, name) => new DecoTemplate { DecoTemplateGroupId = request.DecoTemplateGroupId, Name = name }); } private static async Task> ValidateDecoTemplateGroupExists( TvContext dbContext, CreateDecoTemplate request) { bool decoTemplateGroupExists = await dbContext.DecoTemplateGroups.AnyAsync(dtg => dtg.Id == request.DecoTemplateGroupId); return decoTemplateGroupExists ? Success(Unit.Default) : BaseError.New("Deco template group does not exist"); } private static async Task> ValidateDecoTemplateName( TvContext dbContext, CreateDecoTemplate request) { if (string.IsNullOrWhiteSpace(request.Name) || request.Name.Length > 50) { return BaseError.New($"Deco template name \"{request.Name}\" is invalid"); } bool duplicateName = await dbContext.DecoTemplates .AnyAsync(r => r.DecoTemplateGroupId == request.DecoTemplateGroupId && r.Name == request.Name); return duplicateName ? BaseError.New($"A deco template named \"{request.Name}\" already exists in that deco template group") : Success(request.Name); } }