using System.Net.Http.Json;
using System.Text.Json;
using Microsoft.Extensions.Logging;
using PSLauncher.Models;

namespace PSLauncher.Core.Manifests;

public sealed class ManifestService : IManifestService
{
    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNameCaseInsensitive = true
    };

    private readonly HttpClient _http;
    private readonly Func<string> _serverBaseUrlProvider;
    private readonly ILogger<ManifestService> _logger;

    public ManifestService(HttpClient http, Func<string> serverBaseUrlProvider, ILogger<ManifestService> logger)
    {
        _http = http;
        _serverBaseUrlProvider = serverBaseUrlProvider;
        _logger = logger;
    }

    public async Task<RemoteManifest> FetchAsync(CancellationToken ct)
    {
        var url = TrimSlash(_serverBaseUrlProvider()) + "/manifest";
        _logger.LogInformation("Fetching manifest: {Url}", url);
        using var req = new HttpRequestMessage(HttpMethod.Get, url);
        // Bypass des caches intermédiaires — l'utilisateur a explicitement cliqué « Vérifier ».
        req.Headers.CacheControl = new System.Net.Http.Headers.CacheControlHeaderValue
        {
            NoCache = true,
            NoStore = true,
        };
        req.Headers.Pragma.ParseAdd("no-cache");
        using var resp = await _http.SendAsync(req, ct).ConfigureAwait(false);
        resp.EnsureSuccessStatusCode();
        var manifest = await resp.Content.ReadFromJsonAsync<RemoteManifest>(JsonOptions, ct).ConfigureAwait(false)
                       ?? throw new InvalidOperationException("Empty manifest");
        return manifest;
    }

    public async Task<string> FetchReleaseNotesAsync(string url, CancellationToken ct)
    {
        _logger.LogInformation("Fetching release notes: {Url}", url);
        using var resp = await _http.GetAsync(url, ct).ConfigureAwait(false);
        resp.EnsureSuccessStatusCode();
        return await resp.Content.ReadAsStringAsync(ct).ConfigureAwait(false);
    }

    private static string TrimSlash(string s) => s.TrimEnd('/');
}
