using System.Net.Http.Json; using System.Text.Json.Serialization; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using RealCV.Application.Helpers; namespace RealCV.Infrastructure.Clients; public sealed class FcaRegisterClient { private readonly HttpClient _httpClient; private readonly ILogger _logger; private readonly string _apiKey; public FcaRegisterClient( HttpClient httpClient, IOptions options, ILogger logger) { _httpClient = httpClient; _logger = logger; _apiKey = options.Value.ApiKey; _httpClient.BaseAddress = new Uri("https://register.fca.org.uk/services/V0.1/"); _httpClient.DefaultRequestHeaders.Add("X-Auth-Email", options.Value.Email); _httpClient.DefaultRequestHeaders.Add("X-Auth-Key", _apiKey); } public async Task SearchIndividualsAsync(string name, int page = 1) { try { var encodedName = Uri.EscapeDataString(name); var url = $"Individuals?q={encodedName}&page={page}"; _logger.LogDebug("Searching FCA for individual: {Name}", name); var response = await _httpClient.GetAsync(url); if (!response.IsSuccessStatusCode) { _logger.LogWarning("FCA API returned {StatusCode} for search: {Name}", response.StatusCode, name); return null; } return await response.Content.ReadFromJsonAsync(JsonDefaults.ApiClient); } catch (Exception ex) { _logger.LogError(ex, "Error searching FCA for individual: {Name}", name); return null; } } public async Task GetIndividualAsync(string individualReferenceNumber) { try { var url = $"Individuals/{individualReferenceNumber}"; _logger.LogDebug("Getting FCA individual: {IRN}", individualReferenceNumber); var response = await _httpClient.GetAsync(url); if (!response.IsSuccessStatusCode) { _logger.LogWarning("FCA API returned {StatusCode} for IRN: {IRN}", response.StatusCode, individualReferenceNumber); return null; } var wrapper = await response.Content.ReadFromJsonAsync(JsonDefaults.ApiClient); return wrapper?.Data?.FirstOrDefault(); } catch (Exception ex) { _logger.LogError(ex, "Error getting FCA individual: {IRN}", individualReferenceNumber); return null; } } public async Task SearchFirmsAsync(string name, int page = 1) { try { var encodedName = Uri.EscapeDataString(name); var url = $"Firms?q={encodedName}&page={page}"; var response = await _httpClient.GetAsync(url); if (!response.IsSuccessStatusCode) { return null; } return await response.Content.ReadFromJsonAsync(JsonDefaults.ApiClient); } catch (Exception ex) { _logger.LogError(ex, "Error searching FCA for firm: {Name}", name); return null; } } } public class FcaOptions { public string ApiKey { get; set; } = string.Empty; public string Email { get; set; } = string.Empty; } // Response models public class FcaIndividualResponse { public List? Data { get; set; } public FcaPagination? Pagination { get; set; } } public class FcaIndividualSearchItem { [JsonPropertyName("Individual Reference Number")] public string? IndividualReferenceNumber { get; set; } public string? Name { get; set; } public string? Status { get; set; } [JsonPropertyName("Current Employer(s)")] public string? CurrentEmployers { get; set; } } public class FcaIndividualDetailsWrapper { public List? Data { get; set; } } public class FcaIndividualDetails { [JsonPropertyName("Individual Reference Number")] public string? IndividualReferenceNumber { get; set; } public string? Name { get; set; } public string? Status { get; set; } [JsonPropertyName("Effective Date")] public string? EffectiveDate { get; set; } [JsonPropertyName("Controlled Functions")] public List? ControlledFunctions { get; set; } [JsonPropertyName("Previous Employments")] public List? PreviousEmployments { get; set; } } public class FcaControlledFunction { [JsonPropertyName("Controlled Function")] public string? ControlledFunction { get; set; } [JsonPropertyName("Firm Name")] public string? FirmName { get; set; } [JsonPropertyName("Firm Reference Number")] public string? FirmReferenceNumber { get; set; } [JsonPropertyName("Status")] public string? Status { get; set; } [JsonPropertyName("Effective From")] public string? EffectiveFrom { get; set; } } public class FcaPreviousEmployment { [JsonPropertyName("Firm Name")] public string? FirmName { get; set; } [JsonPropertyName("Firm Reference Number")] public string? FirmReferenceNumber { get; set; } [JsonPropertyName("Start Date")] public string? StartDate { get; set; } [JsonPropertyName("End Date")] public string? EndDate { get; set; } } public class FcaFirmResponse { public List? Data { get; set; } public FcaPagination? Pagination { get; set; } } public class FcaFirmSearchItem { [JsonPropertyName("Firm Reference Number")] public string? FirmReferenceNumber { get; set; } [JsonPropertyName("Firm Name")] public string? FirmName { get; set; } public string? Status { get; set; } } public class FcaPagination { public int Page { get; set; } public int TotalPages { get; set; } public int TotalItems { get; set; } }