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

namespace Backend.Endpoints;

public static partial class PublicEndpoints
{
    private static async Task<IResult> GetWinnerArchive(int year, AwardsDbContext db)
    {
        var latestPublishedWinnerYear = await db.Results
            .AsNoTracking()
            .Where(result => result.Season.WinnersPublishedAt != null)
            .Select(result => (int?)result.Season.Year)
            .MaxAsync();

        var archivedWinnerRows = await db.ArchivedWinners
            .AsNoTracking()
            .Where(item => item.Year == year)
            .OrderBy(item => item.Category)
            .ThenBy(item => item.Subcategory)
            .ThenBy(item => item.WinnerName)
            .ToArrayAsync();
        if (archivedWinnerRows.Length > 0)
        {
            var archivedItems = archivedWinnerRows
                .Select(item =>
                {
                    var metadata = SeasonMappings.InferProfileMetadataFromUrl(item.WinnerUrl, item.WinnerName);
                    return new WinnerArchiveItemDto(
                        item.Subcategory,
                        item.Category,
                        item.WinnerName,
                        metadata.Slug,
                        metadata.Platform,
                        item.WinnerUrl,
                        null,
                        null,
                        null,
                        null);
                })
                .ToArray();

            return Results.Ok(new WinnerArchiveResponse(year, archivedItems));
        }

        var season = await db.Seasons
            .AsNoTracking()
            .Where(item => item.Year == year)
            .Select(item => new { item.Id, item.Year, item.WinnersPublishedAt })
            .FirstOrDefaultAsync();
        if (season is null)
        {
            return Results.Ok(new WinnerArchiveResponse(year, []));
        }

        if (season.WinnersPublishedAt is null)
        {
            return Results.Ok(new WinnerArchiveResponse(year, []));
        }

        if (latestPublishedWinnerYear == season.Year)
        {
            return Results.Ok(new WinnerArchiveResponse(year, []));
        }

        var winnerRows = await db.Results
            .AsNoTracking()
            .Include(result => result.Candidate)
            .Where(result => result.SeasonId == season.Id)
            .OrderBy(result => result.CategoryName)
            .Select(result => new
            {
                CategoryGroup = result.Category.GroupName,
                result.CategoryName,
                WinnerName = result.Candidate.DisplayName,
                WinnerSlug = result.Candidate.ChannelSlug,
                WinnerPlatform = result.Candidate.Platform,
                ClipUrl = result.Candidate.ClipCompilationUrl,
                ClipTitle = result.Candidate.ClipCompilationTitle,
                ClipPlatform = result.Candidate.ClipCompilationPlatform,
                ClipEmbedStatus = result.Candidate.ClipEmbedStatus,
            })
            .ToArrayAsync();

        var items = winnerRows
            .Select(result => new WinnerArchiveItemDto(
                result.CategoryGroup,
                result.CategoryName,
                result.WinnerName,
                result.WinnerSlug,
                result.WinnerPlatform,
                SeasonMappings.BuildProfileUrl(result.WinnerPlatform, result.WinnerSlug),
                result.ClipUrl,
                result.ClipTitle,
                result.ClipPlatform,
                result.ClipEmbedStatus))
            .ToArray();

        return Results.Ok(new WinnerArchiveResponse(year, items));
    }
}
