@page "/catalogue"
@using DeepDrftManager.Services
@using DeepDrftModels.Enums
@attribute [Authorize]
@layout Layout.CmsLayout
@inject NavigationManager Nav
@inject ICmsReleaseService CmsReleaseService
@inject ILogger<Index> Logger

<PageTitle>Deep DRFT Management - Catalogue</PageTitle>

<MudContainer MaxWidth="MaxWidth.Large" Class="mt-8">
    <MudText Typo="Typo.h3" Class="mb-6">Catalogue</MudText>

    <MudGrid Spacing="4">
        @foreach (var card in Cards)
        {
            <MudItem xs="12" sm="4">
                @SummaryCard(card)
            </MudItem>
        }
    </MudGrid>
</MudContainer>

@code {
    // One card per release medium. Each deep-links to /releases with the medium tab pre-selected via the
    // same ?medium= convention the Add Track buttons use. The count is that medium's release total.
    private sealed record MediumCard(ReleaseMedium Medium, string Label, string Icon, Color Color);

    private static readonly IReadOnlyList<MediumCard> Cards = new[]
    {
        new MediumCard(ReleaseMedium.Cut, "CUTS", Icons.Material.Filled.Album, Color.Primary),
        new MediumCard(ReleaseMedium.Session, "SESSIONS", Icons.Material.Filled.Mic, Color.Secondary),
        new MediumCard(ReleaseMedium.Mix, "MIXES", Icons.Material.Filled.GraphicEq, Color.Tertiary),
    };

    // Medium → release count (null while loading or on failure). Each medium's count is one cheap paged
    // read (pageSize 1) for its TotalCount, run concurrently.
    private readonly Dictionary<ReleaseMedium, int?> _counts = new();
    private readonly HashSet<ReleaseMedium> _loading = Cards.Select(c => c.Medium).ToHashSet();

    protected override async Task OnInitializedAsync()
    {
        // Each loader calls StateHasChanged in its finally block so its card updates as soon as its own
        // fetch returns, rather than blocking on the slowest of the three.
        await Task.WhenAll(Cards.Select(c => LoadCountAsync(c.Medium)));
    }

    private async Task LoadCountAsync(ReleaseMedium medium)
    {
        try
        {
            // pageSize 1 — we only need TotalCount, not the rows. Sort column is required by the API but
            // immaterial to the count.
            var result = await CmsReleaseService.GetPagedAsync(
                medium, page: 1, pageSize: 1, sortColumn: "Title", sortDescending: false);
            _counts[medium] = result.Success && result.Value is not null ? result.Value.TotalCount : null;
            if (!result.Success)
            {
                Logger.LogWarning("Dashboard {Medium} count failed: {Error}",
                    medium, result.Messages.FirstOrDefault()?.Message ?? "Unknown error");
            }
        }
        finally
        {
            _loading.Remove(medium);
            StateHasChanged();
        }
    }

    private RenderFragment SummaryCard(MediumCard card) => __builder =>
    {
        var loading = _loading.Contains(card.Medium);
        var count = _counts.GetValueOrDefault(card.Medium);
        <MudCard Elevation="8" Style="height: 100%;">
            <MudCardContent>
                <MudStack AlignItems="AlignItems.Center" Spacing="2" Class="py-4">
                    <MudIcon Icon="@card.Icon" Color="@card.Color" Size="Size.Large" />
                    @if (loading)
                    {
                        <MudProgressCircular Color="@card.Color" Indeterminate="true" Size="Size.Small" />
                    }
                    else
                    {
                        <MudText Typo="Typo.h3" Color="@card.Color">@(count?.ToString() ?? "—")</MudText>
                    }
                    <MudText Typo="Typo.subtitle1" Class="mud-text-secondary text-uppercase">@card.Label</MudText>
                </MudStack>
            </MudCardContent>
            <MudCardActions Class="justify-center pb-4">
                <MudButton Variant="Variant.Text" Color="@card.Color" EndIcon="@Icons.Material.Filled.ArrowForward"
                           OnClick="@(() => Nav.NavigateTo(ReleasesHref(card.Medium)))">
                    View
                </MudButton>
            </MudCardActions>
        </MudCard>
    };

    // Deep-link to the Releases page with this medium's tab pre-selected. Mirrors the ?medium= seed the
    // Add Track buttons use; the Releases page reads it to set the active tab.
    private static string ReleasesHref(ReleaseMedium medium) =>
        $"/releases?medium={medium.ToString().ToLowerInvariant()}";
}
