using Backend.Contracts;
using Backend.Data;
using Backend.Common;
using Backend.Services;
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 subcategoryTemplates = SeasonSubcategoryTemplateSettings.Read(season, season.Categories);
        var publicCategories = season.Categories
            .Where(category => SeasonSubcategoryTemplateSettings.MatchesTemplate(category, subcategoryTemplates))
            .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
                    .Where(candidate => !string.Equals(candidate.AcceptanceStatus, "declined", StringComparison.OrdinalIgnoreCase))
                    .Select(candidate =>
                {
                    var clip = ResolveCandidateClip(candidate, clipsByCandidateId, clipsByCreatorKey);
                    var candidateClipUrl = string.IsNullOrWhiteSpace(candidate.ClipCompilationUrl)
                        || string.Equals(candidate.ClipEmbedStatus, "blocked", StringComparison.OrdinalIgnoreCase)
                            ? null
                            : candidate.ClipCompilationUrl.Trim();
                    var clipUrl = candidateClipUrl ?? clip?.ClipUrl;
                    var clipTitle = candidateClipUrl is not null
                        ? string.IsNullOrWhiteSpace(candidate.ClipCompilationTitle) ? "Highlight-Clip ansehen" : candidate.ClipCompilationTitle.Trim()
                        : clip?.Title;
                    var clipPlatform = candidateClipUrl is not null
                        ? string.IsNullOrWhiteSpace(candidate.ClipCompilationPlatform) ? candidate.Platform : candidate.ClipCompilationPlatform.Trim()
                        : clip?.Platform;
                    var clipEmbedStatus = candidateClipUrl is not null
                        ? candidate.ClipEmbedStatus
                        : null;

                    return new CandidateSummaryDto(
                        candidate.Id,
                        candidate.DisplayName,
                        candidate.ChannelSlug,
                        SeasonMappings.BuildProfileUrl(candidate.Platform, candidate.ChannelSlug),
                        candidate.Platform,
                        clipUrl,
                        clipTitle,
                        clipPlatform,
                        clipEmbedStatus);
                }).ToArray()))
                .ToArray()));
    }
}
