using DeepDrftModels.DTOs;
using Models.Common;
using NetBlocks.Models;
using System.Text.Json;
using Microsoft.AspNetCore.Http;

namespace DeepDrftPublic.Client.Clients;

/// <summary>
/// HTTP client for the release read surface (Phase 9). Uses the named <c>"DeepDrft.API"</c>
/// client like <see cref="TrackClient"/>: on WASM it points at the public host and proxies
/// through <c>ReleaseProxyController</c>; on SSR prerender it points directly at DeepDrftAPI.
/// All routes are unauthenticated reads. Responses deserialize as bare DTOs (no ApiResultDto
/// envelope), matching the API's <c>Ok(value)</c> shape.
/// </summary>
public class ReleaseClient
{
    private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNameCaseInsensitive = true };

    private readonly HttpClient _http;

    public ReleaseClient(IHttpClientFactory httpClientFactory)
    {
        _http = httpClientFactory.CreateClient("DeepDrft.API");
    }

    public async Task<ApiResult<PagedResult<ReleaseDto>>> GetPaged(
        string? medium,
        int page,
        int pageSize,
        string? sortColumn = null,
        bool sortDescending = false,
        string? search = null,
        string? genre = null)
    {
        var queryArgs = new Dictionary<string, string?>
        {
            ["page"] = page.ToString(),
            ["pageSize"] = pageSize.ToString()
        };

        if (!string.IsNullOrEmpty(medium))
            queryArgs["medium"] = medium;

        if (!string.IsNullOrEmpty(search))
            queryArgs["q"] = search;

        if (!string.IsNullOrEmpty(genre))
            queryArgs["genre"] = genre;

        if (!string.IsNullOrEmpty(sortColumn))
            queryArgs["sortColumn"] = sortColumn;

        if (sortDescending)
            queryArgs["sortDescending"] = "true";

        string query = QueryString.Create(queryArgs).ToString();

        var response = await _http.GetAsync($"api/release{query}");

        if (!response.IsSuccessStatusCode)
            return ApiResult<PagedResult<ReleaseDto>>.CreateFailResult($"HTTP {(int)response.StatusCode}");

        var json = await response.Content.ReadAsStringAsync();
        var paged = JsonSerializer.Deserialize<PagedResult<ReleaseDto>>(json, JsonOptions);

        return paged is not null
            ? ApiResult<PagedResult<ReleaseDto>>.CreatePassResult(paged)
            : ApiResult<PagedResult<ReleaseDto>>.CreateFailResult("Failed to deserialize response");
    }

    public async Task<ApiResult<ReleaseDto>> GetByEntryKey(string entryKey)
    {
        var response = await _http.GetAsync($"api/release/{Uri.EscapeDataString(entryKey)}");

        if (!response.IsSuccessStatusCode)
            return ApiResult<ReleaseDto>.CreateFailResult($"HTTP {(int)response.StatusCode}");

        var json = await response.Content.ReadAsStringAsync();
        var release = JsonSerializer.Deserialize<ReleaseDto>(json, JsonOptions);

        return release is not null
            ? ApiResult<ReleaseDto>.CreatePassResult(release)
            : ApiResult<ReleaseDto>.CreateFailResult("Failed to deserialize response");
    }
}
