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

namespace NexusShell.Services.ControlCenter;

public sealed class NexusControlCenterApiClient
{
    private readonly HttpClient _http;
    private readonly string? _baseUrl;

    public NexusControlCenterApiClient(HttpClient http, string? baseUrl)
    {
        _http = http;
        _baseUrl = string.IsNullOrWhiteSpace(baseUrl) ? null : baseUrl.TrimEnd('/');
    }

    public bool IsConfigured => !string.IsNullOrWhiteSpace(_baseUrl);

    public async Task<NexusControlCenterDashboard?> TryFetchDashboardAsync(CancellationToken ct = default)
    {
        if (_baseUrl is null)
        {
            return null;
        }

        try
        {
            var response = await _http.GetAsync($"{_baseUrl}/api/control-center/dashboard", ct);
            if (!response.IsSuccessStatusCode)
            {
                return null;
            }

            return await response.Content.ReadFromJsonAsync<NexusControlCenterDashboard>(cancellationToken: ct);
        }
        catch
        {
            return null;
        }
    }

    public async Task<NexusControlCenterPresenceApiResponse?> TryFetchPresenceAsync(CancellationToken ct = default)
    {
        if (_baseUrl is null)
        {
            return null;
        }

        try
        {
            var response = await _http.GetAsync($"{_baseUrl}/api/presence", ct);
            if (!response.IsSuccessStatusCode)
            {
                return null;
            }

            return await response.Content.ReadFromJsonAsync<NexusControlCenterPresenceApiResponse>(cancellationToken: ct);
        }
        catch
        {
            return null;
        }
    }

    public async Task<NexusControlCenterDeviceStatusApiResponse?> TryFetchDeviceStatusAsync(CancellationToken ct = default)
    {
        if (_baseUrl is null)
        {
            return null;
        }

        try
        {
            var response = await _http.GetAsync($"{_baseUrl}/api/devices/status", ct);
            if (!response.IsSuccessStatusCode)
            {
                return null;
            }

            return await response.Content.ReadFromJsonAsync<NexusControlCenterDeviceStatusApiResponse>(cancellationToken: ct);
        }
        catch
        {
            return null;
        }
    }
}

public sealed class NexusControlCenterDashboard
{
    [JsonPropertyName("generatedAtUtc")]
    public DateTime GeneratedAtUtc { get; init; }

    [JsonPropertyName("organizationCount")]
    public int OrganizationCount { get; init; }

    [JsonPropertyName("deviceCount")]
    public int DeviceCount { get; init; }

    [JsonPropertyName("pendingEnrollmentCount")]
    public int PendingEnrollmentCount { get; init; }

    [JsonPropertyName("organizations")]
    public IReadOnlyList<NexusControlCenterDashboardOrganization> Organizations { get; init; } = [];

    [JsonPropertyName("devices")]
    public IReadOnlyList<NexusControlCenterDashboardDevice> Devices { get; init; } = [];

    [JsonPropertyName("pendingEnrollments")]
    public IReadOnlyList<NexusControlCenterDashboardPendingEnrollment> PendingEnrollments { get; init; } = [];

    [JsonPropertyName("trustSummary")]
    public NexusControlCenterDashboardTrustSummary? TrustSummary { get; init; }

    [JsonPropertyName("policies")]
    public IReadOnlyList<NexusControlCenterDashboardPolicy> Policies { get; init; } = [];
}

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

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

    [JsonPropertyName("userCount")]
    public int UserCount { get; init; }

    [JsonPropertyName("deviceCount")]
    public int DeviceCount { get; init; }
}

public sealed class NexusControlCenterDashboardDevice
{
    [JsonPropertyName("deviceId")]
    public string DeviceId { get; init; } = string.Empty;

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

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

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

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

public sealed class NexusControlCenterDashboardPendingEnrollment
{
    [JsonPropertyName("deviceId")]
    public string DeviceId { get; init; } = string.Empty;

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

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

public sealed class NexusControlCenterDashboardTrustSummary
{
    [JsonPropertyName("trusted")]
    public int Trusted { get; init; }

    [JsonPropertyName("pending")]
    public int Pending { get; init; }

    [JsonPropertyName("blocked")]
    public int Blocked { get; init; }

    [JsonPropertyName("unknown")]
    public int Unknown { get; init; }
}

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

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

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

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

public sealed class NexusControlCenterPresenceApiResponse
{
    [JsonPropertyName("generatedAtUtc")]
    public DateTime GeneratedAtUtc { get; init; }

    [JsonPropertyName("offlineThresholdSeconds")]
    public int OfflineThresholdSeconds { get; init; }

    [JsonPropertyName("onlineCount")]
    public int OnlineCount { get; init; }

    [JsonPropertyName("offlineCount")]
    public int OfflineCount { get; init; }

    [JsonPropertyName("warningCount")]
    public int WarningCount { get; init; }

    [JsonPropertyName("criticalCount")]
    public int CriticalCount { get; init; }

    [JsonPropertyName("devices")]
    public IReadOnlyList<NexusControlCenterPresenceApiDevice> Devices { get; init; } = [];
}

public sealed class NexusControlCenterPresenceApiDevice
{
    [JsonPropertyName("deviceId")]
    public string DeviceId { get; init; } = string.Empty;

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

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

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

    [JsonPropertyName("online")]
    public bool Online { get; init; }

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

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

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

    [JsonPropertyName("lastSeenUtc")]
    public DateTime? LastSeenUtc { get; init; }
}

public sealed class NexusControlCenterDeviceStatusApiResponse
{
    [JsonPropertyName("generatedAtUtc")]
    public DateTime GeneratedAtUtc { get; init; }

    [JsonPropertyName("offlineThresholdSeconds")]
    public int OfflineThresholdSeconds { get; init; }

    [JsonPropertyName("onlineCount")]
    public int OnlineCount { get; init; }

    [JsonPropertyName("offlineCount")]
    public int OfflineCount { get; init; }

    [JsonPropertyName("warningCount")]
    public int WarningCount { get; init; }

    [JsonPropertyName("criticalCount")]
    public int CriticalCount { get; init; }

    [JsonPropertyName("devices")]
    public IReadOnlyList<NexusControlCenterPresenceApiDevice> Devices { get; init; } = [];
}
