using Backend.Contracts; using Backend.Common; using Backend.Data; using Backend.Domain; using Backend.Services; using Microsoft.EntityFrameworkCore; namespace Backend.Endpoints; public static partial class AdminSeasonManagementEndpoints { private static async Task CreateCandidate( HttpContext context, int seasonId, UpsertCandidateRequest request, AwardsDbContext db, IAdminAuditService adminAuditService) { var session = AdminEndpointConventions.CurrentSession(context); var validationError = ValidateCandidateRequest(request); if (validationError is not null) { return validationError; } var category = await db.Categories.FirstOrDefaultAsync(item => item.Id == request.CategoryId && item.SeasonId == seasonId); if (category is null) { return Results.BadRequest(new { message = "The selected category does not exist in this season." }); } var normalizedDisplayName = request.DisplayName.Trim(); var normalizedChannelSlug = request.ChannelSlug.Trim(); if (await db.Candidates.AnyAsync(item => item.SeasonId == seasonId && item.CategoryId == request.CategoryId && (item.DisplayName.ToLower() == normalizedDisplayName.ToLower() || item.ChannelSlug.ToLower() == normalizedChannelSlug.ToLower()))) { return Results.BadRequest(new { message = "A candidate with the same display name or channel slug already exists in this category." }); } var candidate = new Candidate { SeasonId = seasonId, CategoryId = request.CategoryId, DisplayName = normalizedDisplayName, ChannelSlug = normalizedChannelSlug, Platform = request.Platform.Trim(), }; db.Candidates.Add(candidate); adminAuditService.AddEntry( session.TwitchUserId, "candidate.create", "candidate", request.DisplayName.Trim(), $"Kandidat {request.DisplayName.Trim()} wurde angelegt.", new { seasonId, request.CategoryId, request.Platform }, RequestMetadataReader.Read(context)); await db.SaveChangesAsync(context.RequestAborted); return Results.Ok(new { saved = true, candidateId = candidate.Id }); } private static async Task UpdateCandidate( HttpContext context, int candidateId, UpsertCandidateRequest request, AwardsDbContext db, IAdminAuditService adminAuditService) { var session = AdminEndpointConventions.CurrentSession(context); var validationError = ValidateCandidateRequest(request); if (validationError is not null) { return validationError; } var candidate = await db.Candidates.FirstOrDefaultAsync(item => item.Id == candidateId); if (candidate is null) { return Results.NotFound(); } var targetCategory = await db.Categories.FirstOrDefaultAsync(item => item.Id == request.CategoryId && item.SeasonId == candidate.SeasonId); if (targetCategory is null) { return Results.BadRequest(new { message = "The selected category does not exist in this season." }); } var normalizedDisplayName = request.DisplayName.Trim(); var normalizedChannelSlug = request.ChannelSlug.Trim(); if (await db.Candidates.AnyAsync(item => item.SeasonId == candidate.SeasonId && item.CategoryId == request.CategoryId && item.Id != candidateId && (item.DisplayName.ToLower() == normalizedDisplayName.ToLower() || item.ChannelSlug.ToLower() == normalizedChannelSlug.ToLower()))) { return Results.BadRequest(new { message = "A candidate with the same display name or channel slug already exists in this category." }); } candidate.CategoryId = request.CategoryId; candidate.DisplayName = normalizedDisplayName; candidate.ChannelSlug = normalizedChannelSlug; candidate.Platform = request.Platform.Trim(); adminAuditService.AddEntry( session.TwitchUserId, "candidate.update", "candidate", candidate.Id.ToString(), $"Kandidat {request.DisplayName.Trim()} wurde aktualisiert.", new { request.CategoryId, request.Platform }, RequestMetadataReader.Read(context)); await db.SaveChangesAsync(context.RequestAborted); return Results.Ok(new { saved = true, candidateId = candidate.Id }); } private static async Task DeleteCandidate( HttpContext context, int candidateId, AwardsDbContext db, IAdminAuditService adminAuditService) { var session = AdminEndpointConventions.CurrentSession(context); var candidate = await db.Candidates.FirstOrDefaultAsync(item => item.Id == candidateId); if (candidate is null) { return Results.NotFound(); } db.Candidates.Remove(candidate); adminAuditService.AddEntry( session.TwitchUserId, "candidate.delete", "candidate", candidate.Id.ToString(), $"Kandidat {candidate.DisplayName} wurde gelöscht.", new { candidate.CategoryId, candidate.Platform }, RequestMetadataReader.Read(context)); await db.SaveChangesAsync(context.RequestAborted); return Results.Ok(new { deleted = true, candidateId }); } }