using ErsatzTV.Core; using ErsatzTV.Core.Domain.Scheduling; using ErsatzTV.Infrastructure.Data; using Microsoft.EntityFrameworkCore; namespace ErsatzTV.Application.Scheduling; public class CreateTemplateHandler(IDbContextFactory dbContextFactory) : IRequestHandler> { public async Task> Handle( CreateTemplate request, CancellationToken cancellationToken) { await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken); Validation validation = await Validate(dbContext, request); return await validation.Apply(profile => PersistTemplate(dbContext, profile)); } private static async Task PersistTemplate(TvContext dbContext, Template template) { await dbContext.Templates.AddAsync(template); await dbContext.SaveChangesAsync(); await dbContext.Entry(template).Reference(t => t.TemplateGroup).LoadAsync(); return Mapper.ProjectToViewModel(template); } private static async Task> Validate(TvContext dbContext, CreateTemplate request) { Validation templateGroupValidation = await ValidateTemplateGroupExists(dbContext, request); Validation nameValidation = await ValidateTemplateName(dbContext, request); return (templateGroupValidation, nameValidation).Apply((_, name) => new Template { TemplateGroupId = request.TemplateGroupId, Name = name }); } private static async Task> ValidateTemplateGroupExists( TvContext dbContext, CreateTemplate request) { bool templateGroupExists = await dbContext.TemplateGroups.AnyAsync(tg => tg.Id == request.TemplateGroupId); return templateGroupExists ? Success(Unit.Default) : BaseError.New("Template group does not exist"); } private static async Task> ValidateTemplateName( TvContext dbContext, CreateTemplate request) { if (string.IsNullOrWhiteSpace(request.Name) || request.Name.Length > 50) { return BaseError.New($"Template name \"{request.Name}\" is invalid"); } bool duplicateName = await dbContext.Templates .AnyAsync(r => r.TemplateGroupId == request.TemplateGroupId && r.Name == request.Name); return duplicateName ? BaseError.New($"A template named \"{request.Name}\" already exists in that template group") : Success(request.Name); } }