using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace ModpackLauncher.Services;

/// <summary>
/// Friend-side wrapper for the brass-sigil-server's public whitelist endpoints.
/// Exists so the launcher can:
///   - Send a "please add me" request without the friend needing to share their
///     MC username with the admin out-of-band.
///   - Poll status afterwards so the launcher UI reflects pending/approved/denied.
/// </summary>
public sealed class WhitelistRequestService
{
    private static readonly HttpClient _http = new() { Timeout = TimeSpan.FromSeconds(10) };

    public sealed class StatusResponse
    {
        [JsonPropertyName("ok")]     public bool Ok { get; set; }
        [JsonPropertyName("status")] public string? Status { get; set; }
    }

    public sealed class RequestResponse
    {
        [JsonPropertyName("ok")]     public bool Ok { get; set; }
        [JsonPropertyName("status")] public string? Status { get; set; }
        [JsonPropertyName("error")]  public string? Error { get; set; }
    }

    /// <summary>
    /// Returns "pending" / "approved" / "denied" / "unknown" / "" (network error).
    /// </summary>
    public async Task<string> GetStatusAsync(string panelUrl, string username)
    {
        try
        {
            var url = $"{panelUrl.TrimEnd('/')}/api/whitelist/status?username={Uri.EscapeDataString(username)}";
            var resp = await _http.GetFromJsonAsync<StatusResponse>(url);
            return resp?.Status ?? "";
        }
        catch
        {
            return "";
        }
    }

    public async Task<RequestResponse> SubmitAsync(string panelUrl, string username, string? message = null)
    {
        try
        {
            var url = $"{panelUrl.TrimEnd('/')}/api/whitelist/request";
            var resp = await _http.PostAsJsonAsync(url, new { username, message });
            var body = await resp.Content.ReadFromJsonAsync<RequestResponse>();
            if (body is null) return new RequestResponse { Ok = false, Error = "Empty response." };
            if (!resp.IsSuccessStatusCode && string.IsNullOrEmpty(body.Error))
                body.Error = $"HTTP {(int)resp.StatusCode}";
            return body;
        }
        catch (Exception ex)
        {
            return new RequestResponse { Ok = false, Error = ex.Message };
        }
    }
}
