using Backend.Contracts; using Backend.Data; using Microsoft.EntityFrameworkCore; namespace Backend.Endpoints; public static partial class AdminSeasonManagementEndpoints { private static async Task GetSeasonDetail(int seasonId, AwardsDbContext db) { var season = await db.Seasons .AsNoTracking() .FirstOrDefaultAsync(item => item.Id == seasonId); if (season is null) { return Results.NotFound(); } var candidates = await db.Candidates .AsNoTracking() .Where(item => item.SeasonId == seasonId) .OrderBy(item => item.DisplayName) .Select(item => new AdminCandidateItemDto( item.Id, item.CategoryId, item.DisplayName, item.ChannelSlug, item.Platform)) .ToArrayAsync(); var candidateCounts = candidates .GroupBy(item => item.CategoryId) .ToDictionary(grouping => grouping.Key, grouping => grouping.Count()); var categoryRows = await db.Categories .AsNoTracking() .Where(item => item.SeasonId == seasonId) .OrderBy(item => item.SortOrder) .ThenBy(item => item.Name) .Select(category => new { category.Id, category.GroupName, category.Name, category.Slug, category.Description, category.SortOrder, category.MaxNomineesPerUser, }) .ToArrayAsync(); var categories = categoryRows .Select(category => new AdminCategoryItemDto( category.Id, category.GroupName, category.Name, category.Slug, category.Description, category.SortOrder, category.MaxNomineesPerUser, candidateCounts.TryGetValue(category.Id, out var count) ? count : 0)) .ToArray(); var pendingNominations = await db.Nominations .AsNoTracking() .Where(item => item.SeasonId == seasonId && item.Status == "pending" && item.CandidateText != null) .OrderByDescending(item => item.CreatedAt) .Select(item => new AdminNominationReviewItemDto( item.Id, item.CategoryId, item.Category.Name, item.SubmittedByTwitchId, item.CandidateText!, item.StreamUrl, item.Status, item.CreatedAt, item.CandidateId, item.CandidateId != null ? item.Candidate!.DisplayName : null, item.ReviewNote, item.ReviewedByTwitchId, item.ReviewedAt)) .ToArrayAsync(); var reviewedNominations = await db.Nominations .AsNoTracking() .Where(item => item.SeasonId == seasonId && item.Status != "pending") .OrderByDescending(item => item.ReviewedAt ?? item.CreatedAt) .Select(item => new AdminNominationReviewItemDto( item.Id, item.CategoryId, item.Category.Name, item.SubmittedByTwitchId, item.CandidateText ?? (item.CandidateId != null ? item.Candidate!.DisplayName : string.Empty), item.StreamUrl, item.Status, item.CreatedAt, item.CandidateId, item.CandidateId != null ? item.Candidate!.DisplayName : null, item.ReviewNote, item.ReviewedByTwitchId, item.ReviewedAt)) .ToArrayAsync(); var resultItems = await db.Results .AsNoTracking() .Where(item => item.SeasonId == seasonId) .OrderBy(item => item.Category.SortOrder) .ThenBy(item => item.Category.Name) .Select(item => new AdminAwardResultItemDto( item.Id, item.CategoryId, item.Category.Name, item.CandidateId, item.Candidate.DisplayName, item.Candidate.ChannelSlug, item.Candidate.Platform)) .ToArrayAsync(); var clipSubmissions = await db.ClipSubmissions .AsNoTracking() .Where(item => item.SeasonId == seasonId) .OrderByDescending(item => item.CreatedAt) .Select(item => new AdminClipSubmissionItemDto( item.Id, item.CategoryId, item.CandidateId, item.SubmittedByTwitchId, item.ClipUrl, item.Title, item.Creator, item.Platform, item.Status, item.CreatedAt, item.ReviewNote, item.ReviewedByTwitchId, item.ReviewedAt)) .ToArrayAsync(); return Results.Ok(new AdminSeasonDetailResponse( season.Id, season.Year, season.Name, NormalizeSeasonStreamUrl(season.ShowStreamUrl), season.CurrentPhase, season.IsCurrent, season.IsCommunityOnly, season.NominationStartsAt, season.NominationEndsAt, season.VotingStartsAt, season.VotingEndsAt, season.ReviewStartsAt, season.ReviewEndsAt, season.ShowDate, season.ShowStartsAt, categories, candidates, pendingNominations, reviewedNominations, resultItems, clipSubmissions)); } }