using Backend.Contracts; using Backend.Common; using Backend.Data; using Backend.Services; using Microsoft.EntityFrameworkCore; namespace Backend.Endpoints; public static partial class AdminSeasonManagementEndpoints { private static async Task UpdateSeason( HttpContext context, int seasonId, UpdateSeasonRequest request, AwardsDbContext db, IAdminAuditService adminAuditService) { var session = AdminEndpointConventions.CurrentSession(context); var season = await db.Seasons.FirstOrDefaultAsync(item => item.Id == seasonId); if (season is null) { return Results.NotFound(); } var validationError = ValidateSeasonRequest(request); if (validationError is not null) { return validationError; } if (await db.Seasons.AnyAsync(item => item.Id != seasonId && item.Year == request.Year)) { return Results.BadRequest(new { message = $"A season for {request.Year} already exists." }); } var showStreamUrl = NormalizeSeasonStreamUrl(request.ShowStreamUrl); var wasCurrent = season.IsCurrent; var previousPhase = season.CurrentPhase; var previousPhaseKey = SeasonMappings.NormalizePhaseKey(previousPhase); var requestedPhaseKey = SeasonMappings.NormalizePhaseKey(request.CurrentPhase); var shouldValidateReadiness = request.IsCurrent || (string.Equals(requestedPhaseKey, "completed", StringComparison.Ordinal) && !string.Equals(previousPhaseKey, "completed", StringComparison.Ordinal)); if (shouldValidateReadiness) { var readinessIssues = await BuildSeasonReadinessIssuesAsync( db, seasonId, request.CurrentPhase, request.IsCurrent, context.RequestAborted); if (readinessIssues.Length > 0) { return CreateReadinessError(readinessIssues); } } season.Year = request.Year; season.Name = request.Name.Trim(); season.ShowStreamUrl = showStreamUrl; season.CurrentPhase = request.CurrentPhase.Trim(); season.IsCommunityOnly = request.IsCommunityOnly; season.NominationStartsAt = request.NominationStartsAt; season.NominationEndsAt = request.NominationEndsAt; season.VotingStartsAt = request.VotingStartsAt; season.VotingEndsAt = request.VotingEndsAt; season.ReviewStartsAt = request.ReviewStartsAt; season.ReviewEndsAt = request.ReviewEndsAt; season.ShowDate = request.ShowDate; season.ShowStartsAt = request.ShowStartsAt; await UnsetOtherCurrentSeasonsAsync(db, request.IsCurrent && !wasCurrent, seasonId, context.RequestAborted); season.IsCurrent = request.IsCurrent; var actionType = "season.update"; var summary = $"Season {season.Year} wurde aktualisiert."; if (!string.Equals(previousPhase.Trim(), season.CurrentPhase, StringComparison.OrdinalIgnoreCase)) { actionType = "season.phase.update"; summary = $"Phase fuer Season {season.Year} wurde auf {season.CurrentPhase} gesetzt."; } else if (wasCurrent != request.IsCurrent) { actionType = "season.public.update"; summary = request.IsCurrent ? $"Season {season.Year} wurde als Public-Kontext aktiviert." : $"Season {season.Year} wurde aus dem Public-Kontext entfernt."; } adminAuditService.AddEntry( session.TwitchUserId, actionType, "season", season.Id.ToString(), summary, new { request.Year, request.Name, showStreamUrl, previousPhase, request.CurrentPhase, wasCurrent, request.IsCurrent, request.IsCommunityOnly, request.ShowDate, request.ShowStartsAt, }, RequestMetadataReader.Read(context)); await db.SaveChangesAsync(context.RequestAborted); return Results.Ok(new { saved = true, seasonId = season.Id }); } }