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

namespace NexusShell.Services.Identity;

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

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

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

    public async Task<NexusRemoteEnrollmentSyncResult> TryRegisterAsync(
        RemoteEnrollmentPayload payload,
        CancellationToken ct = default)
    {
        if (_baseUrl is null)
        {
            return NexusRemoteEnrollmentSyncResult.Skipped();
        }

        try
        {
            var response = await _http.PostAsJsonAsync($"{_baseUrl}/api/enrollment/register", payload, ct);
            if (!response.IsSuccessStatusCode)
            {
                var body = await response.Content.ReadAsStringAsync(ct);
                return NexusRemoteEnrollmentSyncResult.Failed($"HTTP {(int)response.StatusCode}: {body}");
            }

            var result = await response.Content.ReadFromJsonAsync<RemoteEnrollmentResponse>(cancellationToken: ct);
            return NexusRemoteEnrollmentSyncResult.Success(result?.Status ?? "Pending", result?.Message);
        }
        catch (Exception ex)
        {
            return NexusRemoteEnrollmentSyncResult.Failed(ex.Message);
        }
    }

    public async Task<RemoteEnrollmentStatus?> TryGetStatusAsync(string deviceId, CancellationToken ct = default)
    {
        if (_baseUrl is null || string.IsNullOrWhiteSpace(deviceId))
        {
            return null;
        }

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

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

public sealed class RemoteEnrollmentPayload
{
    [JsonPropertyName("deviceId")]
    public required string DeviceId { get; init; }

    [JsonPropertyName("organizationId")]
    public required string OrganizationId { get; init; }

    [JsonPropertyName("userName")]
    public required string UserName { get; init; }

    [JsonPropertyName("deviceFriendlyName")]
    public required string DeviceFriendlyName { get; init; }

    [JsonPropertyName("computerName")]
    public required string ComputerName { get; init; }

    [JsonPropertyName("os")]
    public string Os { get; init; } = "Windows";

    [JsonPropertyName("shellVersion")]
    public required string ShellVersion { get; init; }

    [JsonPropertyName("agentVersion")]
    public required string AgentVersion { get; init; }
}

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

    [JsonPropertyName("message")]
    public string? Message { get; init; }
}

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

    [JsonPropertyName("trustStatus")]
    public string? TrustStatus { get; init; }

    [JsonPropertyName("message")]
    public string? Message { get; init; }
}
