using Backend.Contracts; using Backend.Data; using Backend.Common; using Microsoft.EntityFrameworkCore; namespace Backend.Endpoints; public static partial class PublicEndpoints { private static async Task GetSeasonCategories(int year, AwardsDbContext db) { var season = await db.Seasons .AsNoTracking() .Include(item => item.Categories.OrderBy(category => category.SortOrder)) .ThenInclude(category => category.Candidates.OrderBy(candidate => candidate.DisplayName)) .FirstOrDefaultAsync(item => item.Year == year); if (season is null) { return Results.NotFound(); } var phaseKey = SeasonMappings.NormalizePhaseKey(season.CurrentPhase); var publicCategories = season.Categories .Where(category => ShouldExposePublicCategory(phaseKey, category.Candidates.Count)) .ToArray(); var publicCategoryIds = publicCategories.Select(category => category.Id).ToArray(); var approvedClips = await db.ClipSubmissions .AsNoTracking() .Where(item => item.SeasonId == season.Id && item.Status == "approved" && item.CategoryId != null && publicCategoryIds.Contains(item.CategoryId.Value)) .Select(item => new PublicCandidateClip( item.CategoryId, item.CandidateId, item.Creator, item.ClipUrl, item.Title, item.Platform, item.CreatedAt, item.ReviewedAt)) .ToArrayAsync(); var clipsByCandidateId = BuildCandidateClipLookup(approvedClips); var clipsByCreatorKey = BuildCreatorClipLookup(approvedClips); return Results.Ok(new SeasonCategoriesResponse( season.Id, season.Year, publicCategories.Select(category => new PublicCategoryDetailDto( category.Id, category.Name, category.GroupName, category.Description, category.MaxNomineesPerUser, category.Candidates.Select(candidate => { var clip = ResolveCandidateClip(candidate, clipsByCandidateId, clipsByCreatorKey); return new CandidateSummaryDto( candidate.Id, candidate.DisplayName, candidate.ChannelSlug, candidate.Platform, clip?.ClipUrl, clip?.Title, clip?.Platform); }).ToArray())) .ToArray())); } }