using DeepDrftModels.DTOs;
using DeepDrftPublic.Client.Services;
namespace DeepDrftPublic.Client.ViewModels;
///
/// State for the Cut album-detail page (/cuts/{id}). Unlike
/// (which resolves a single playable track for Session/Mix), a Cut is multi-track: it loads the
/// release and the full ordered track list for that release. The list is fetched through the
/// existing releaseId-filtered track page sorted by TrackNumber — the explicit 1-based ordinal
/// (Phase 8) that the public read both sorts on and projects onto TrackDto. Scoped; every flag is
/// reset per so a reused instance never bleeds across navigations.
///
public class CutDetailViewModel
{
private readonly IReleaseDataService _releaseData;
private readonly ITrackDataService _trackData;
// A Cut covers the whole album in one page. Matches the gallery's page-size convention; a single
// album never approaches this ceiling (the API caps PageSize at 100 regardless).
private const int AlbumPageSize = 100;
public ReleaseDto? Release { get; private set; }
public IReadOnlyList Tracks { get; private set; } = [];
public bool IsLoading { get; private set; } = true;
public bool NotFound { get; private set; }
public CutDetailViewModel(IReleaseDataService releaseData, ITrackDataService trackData)
{
_releaseData = releaseData;
_trackData = trackData;
}
/// Seed state directly from a bridged prerender payload — no fetch.
public void Restore(ReleaseDto release, IReadOnlyList tracks)
{
Release = release;
Tracks = tracks;
NotFound = false;
IsLoading = false;
}
public async Task Load(long releaseId)
{
IsLoading = true;
NotFound = false;
Release = null;
Tracks = [];
try
{
var releaseResult = await _releaseData.GetById(releaseId);
if (releaseResult is not { Success: true, Value: { } release })
{
NotFound = true;
return;
}
Release = release;
// The album's tracks via the releaseId-filtered page — an exact join, not a title string
// (which collides across same-titled releases and breaks on rename). Sorted by TrackNumber
// so rows render in saved order. A Cut with no streamable tracks simply leaves the list
// empty (the page renders the header with no rows).
var trackResult = await _trackData.GetPage(
pageNumber: 1,
pageSize: AlbumPageSize,
sortColumn: "TrackNumber",
releaseId: release.Id);
if (trackResult is { Success: true, Value: { Items: { } items } })
Tracks = items.ToList();
}
finally
{
IsLoading = false;
}
}
}