using System.Net.Http.Json;
using System.Text.Json.Serialization;
using NexusInstaller.Models;

namespace NexusInstaller.Services;

internal sealed class NexusIdentityApiClient : IDisposable
{
    private readonly HttpClient _http = new() { Timeout = TimeSpan.FromSeconds(10) };

    public async Task<bool> IsHealthyAsync(string baseUrl = NexusLaunchService.IdentityBaseUrl, CancellationToken ct = default)
    {
        try
        {
            var json = await _http.GetFromJsonAsync<HealthResponse>($"{baseUrl.TrimEnd('/')}/health", ct);
            return string.Equals(json?.Status, "healthy", StringComparison.OrdinalIgnoreCase);
        }
        catch
        {
            return false;
        }
    }

    public async Task<IReadOnlyList<OrganizationOption>> GetOrganizationsAsync(
        string baseUrl = NexusLaunchService.IdentityBaseUrl,
        CancellationToken ct = default)
    {
        var orgs = await _http.GetFromJsonAsync<List<ApiOrganization>>(
            $"{baseUrl.TrimEnd('/')}/api/organizations",
            ct);

        return (orgs ?? [])
            .Where(o => !string.IsNullOrWhiteSpace(o.Id) && !string.IsNullOrWhiteSpace(o.Name))
            .Select(o => new OrganizationOption { Id = o.Id, Name = o.Name })
            .ToList();
    }

    public async Task<IReadOnlyList<RoleOption>> GetRolesAsync(
        string baseUrl = NexusLaunchService.IdentityBaseUrl,
        CancellationToken ct = default)
    {
        var roles = await _http.GetFromJsonAsync<List<ApiRole>>(
            $"{baseUrl.TrimEnd('/')}/api/roles",
            ct);

        return (roles ?? [])
            .Where(r => !string.IsNullOrWhiteSpace(r.Name))
            .Select(r => new RoleOption { Id = r.Id ?? r.Name, Name = r.Name })
            .ToList();
    }

    public void Dispose() => _http.Dispose();

    private sealed class HealthResponse
    {
        [JsonPropertyName("status")]
        public string? Status { get; init; }
    }

    private sealed class ApiOrganization
    {
        [JsonPropertyName("id")]
        public string Id { get; init; } = string.Empty;

        [JsonPropertyName("name")]
        public string Name { get; init; } = string.Empty;
    }

    private sealed class ApiRole
    {
        [JsonPropertyName("id")]
        public string? Id { get; init; }

        [JsonPropertyName("name")]
        public string Name { get; init; } = string.Empty;
    }
}
