using DeepDrftModels.DTOs;
using DeepDrftPublic.Client.Services;
namespace DeepDrftPublic.Client.ViewModels;
///
/// State for a single-release detail page (Session, Mix). Loads the release and resolves its
/// playable track. The release read surface exposes no track entry directly, so the playable track
/// is resolved through the existing track gallery filtered by the release's id (an exact join) — for
/// Session/Mix that yields the single track. Scoped; reset every flag per so a
/// reused instance never bleeds across navigations (mirrors TrackDetailViewModel).
///
public class ReleaseDetailViewModel
{
private readonly IReleaseDataService _releaseData;
private readonly ITrackDataService _trackData;
public ReleaseDto? Release { get; private set; }
public TrackDto? Track { get; private set; }
public bool IsLoading { get; private set; } = true;
public bool NotFound { get; private set; }
public ReleaseDetailViewModel(IReleaseDataService releaseData, ITrackDataService trackData)
{
_releaseData = releaseData;
_trackData = trackData;
}
/// Seed state directly from a bridged prerender payload — no fetch.
public void Restore(ReleaseDto release, TrackDto? track)
{
Release = release;
Track = track;
NotFound = false;
IsLoading = false;
}
public async Task Load(long releaseId)
{
IsLoading = true;
NotFound = false;
Release = null;
Track = null;
try
{
var releaseResult = await _releaseData.GetById(releaseId);
if (releaseResult is not { Success: true, Value: { } release })
{
NotFound = true;
return;
}
Release = release;
// Resolve the playable track via the releaseId-filtered track page — an exact join, not a
// title string (which collides across same-titled releases and breaks on rename). Session/Mix
// releases carry a single track; take the first. A release with no streamable track simply
// leaves Track null (the detail page hides the play affordance).
var trackResult = await _trackData.GetPage(
pageNumber: 1, pageSize: 1, releaseId: release.Id);
if (trackResult is { Success: true, Value: { Items: { } items } })
Track = items.FirstOrDefault();
}
finally
{
IsLoading = false;
}
}
}