using DeepDrftModels.DTOs; using Models.Common; using NetBlocks.Models; using System.Text.Json; using System.Web; using Microsoft.AspNetCore.Http; namespace DeepDrftPublic.Client.Clients; public class TrackClient { private readonly HttpClient _http; public TrackClient(IHttpClientFactory httpClientFactory) { _http = httpClientFactory.CreateClient("DeepDrft.API"); } public async Task>> GetPage( int pageNumber, int pageSize, string? sortColumn = null, bool sortDescending = false, string? searchText = null, string? album = null, string? genre = null, long? releaseId = null) { var queryArgs = new Dictionary(){ ["page"] = pageNumber.ToString(), ["pageSize"] = pageSize.ToString() }; if (!string.IsNullOrEmpty(sortColumn)) queryArgs["sortColumn"] = sortColumn; if (sortDescending) queryArgs["sortDescending"] = "true"; if (!string.IsNullOrEmpty(searchText)) queryArgs["q"] = searchText; if (!string.IsNullOrEmpty(album)) queryArgs["album"] = album; if (!string.IsNullOrEmpty(genre)) queryArgs["genre"] = genre; if (releaseId is { } id) queryArgs["releaseId"] = id.ToString(); string query = QueryString.Create(queryArgs).ToString(); var response = await _http.GetAsync($"api/track/page{query}"); if (!response.IsSuccessStatusCode) return ApiResult>.CreateFailResult($"HTTP {(int)response.StatusCode}"); var json = await response.Content.ReadAsStringAsync(); var paged = JsonSerializer.Deserialize>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); return paged is not null ? ApiResult>.CreatePassResult(paged) : ApiResult>.CreateFailResult("Failed to deserialize response"); } /// /// Fetches a random track from the public library. A 404 means the library is empty โ€” a valid /// state, not an error โ€” so it returns a pass result with a null value. Any other non-success /// status is a genuine failure. /// public async Task> GetRandom() { var response = await _http.GetAsync("api/track/random"); if (response.StatusCode == System.Net.HttpStatusCode.NotFound) return ApiResult.CreatePassResult(null); if (!response.IsSuccessStatusCode) return ApiResult.CreateFailResult($"HTTP {(int)response.StatusCode}"); var json = await response.Content.ReadAsStringAsync(); var track = JsonSerializer.Deserialize(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); return track is not null ? ApiResult.CreatePassResult(track) : ApiResult.CreateFailResult("Failed to deserialize response"); } public async Task>> GetAlbums() { var response = await _http.GetAsync("api/track/albums"); if (!response.IsSuccessStatusCode) return ApiResult>.CreateFailResult($"HTTP {(int)response.StatusCode}"); var json = await response.Content.ReadAsStringAsync(); var releases = JsonSerializer.Deserialize>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); return releases is not null ? ApiResult>.CreatePassResult(releases) : ApiResult>.CreateFailResult("Failed to deserialize response"); } public async Task>> GetGenres() { var response = await _http.GetAsync("api/track/genres"); if (!response.IsSuccessStatusCode) return ApiResult>.CreateFailResult($"HTTP {(int)response.StatusCode}"); var json = await response.Content.ReadAsStringAsync(); var genres = JsonSerializer.Deserialize>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); return genres is not null ? ApiResult>.CreatePassResult(genres) : ApiResult>.CreateFailResult("Failed to deserialize response"); } /// /// Fetches the per-track high-res waveform datum, addressed by the track's EntryKey (phase-12 ยง5b). /// A 404 means no high-res datum is stored (a track not yet backfilled) โ€” a valid state, so it /// returns a pass result with a null value and the visualizer blanks gracefully. Any other /// non-success status is a genuine failure. /// public async Task> GetTrackWaveform(string trackEntryKey) { var response = await _http.GetAsync($"api/track/{Uri.EscapeDataString(trackEntryKey)}/waveform/high-res"); if (response.StatusCode == System.Net.HttpStatusCode.NotFound) return ApiResult.CreatePassResult(null); if (!response.IsSuccessStatusCode) return ApiResult.CreateFailResult($"HTTP {(int)response.StatusCode}"); var json = await response.Content.ReadAsStringAsync(); var profile = JsonSerializer.Deserialize(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); return profile is not null ? ApiResult.CreatePassResult(profile) : ApiResult.CreateFailResult("Failed to deserialize response"); } public async Task> GetTrack(string entryKey) { var response = await _http.GetAsync($"api/track/meta/by-key/{Uri.EscapeDataString(entryKey)}"); if (!response.IsSuccessStatusCode) return ApiResult.CreateFailResult($"HTTP {(int)response.StatusCode}"); var json = await response.Content.ReadAsStringAsync(); var track = JsonSerializer.Deserialize(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); return track is not null ? ApiResult.CreatePassResult(track) : ApiResult.CreateFailResult("Failed to deserialize response"); } }