using Backend.Contracts;
using Backend.Data;
using Backend.Common;
using Microsoft.EntityFrameworkCore;

namespace Backend.Endpoints;

public static partial class PublicEndpoints
{
    private static async Task<IResult> 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()));
    }
}
