using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Extensions.Logging;

namespace RealCV.Infrastructure.Clients;

public sealed class SraRegisterClient
{
    private readonly HttpClient _httpClient;
    private readonly ILogger<SraRegisterClient> _logger;

    public SraRegisterClient(
        HttpClient httpClient,
        ILogger<SraRegisterClient> logger)
    {
        _httpClient = httpClient;
        _logger = logger;

        _httpClient.BaseAddress = new Uri("https://sra-prod-apim.azure-api.net/");
    }

    public async Task<SraSolicitorSearchResponse?> SearchSolicitorsAsync(string name, int page = 1, int pageSize = 20)
    {
        try
        {
            var encodedName = Uri.EscapeDataString(name);
            var url = $"solicitors/search?name={encodedName}&page={page}&pageSize={pageSize}";

            _logger.LogDebug("Searching SRA for solicitor: {Name}", name);

            var response = await _httpClient.GetAsync(url);

            if (!response.IsSuccessStatusCode)
            {
                _logger.LogWarning("SRA API returned {StatusCode} for search: {Name}",
                    response.StatusCode, name);
                return null;
            }

            return await response.Content.ReadFromJsonAsync<SraSolicitorSearchResponse>(JsonOptions);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error searching SRA for solicitor: {Name}", name);
            return null;
        }
    }

    public async Task<SraSolicitorDetails?> GetSolicitorAsync(string sraNumber)
    {
        try
        {
            var url = $"solicitors/{sraNumber}";

            _logger.LogDebug("Getting SRA solicitor: {SraNumber}", sraNumber);

            var response = await _httpClient.GetAsync(url);

            if (!response.IsSuccessStatusCode)
            {
                _logger.LogWarning("SRA API returned {StatusCode} for SRA number: {SraNumber}",
                    response.StatusCode, sraNumber);
                return null;
            }

            return await response.Content.ReadFromJsonAsync<SraSolicitorDetails>(JsonOptions);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting SRA solicitor: {SraNumber}", sraNumber);
            return null;
        }
    }

    public async Task<SraOrganisationSearchResponse?> SearchOrganisationsAsync(string name, int page = 1, int pageSize = 20)
    {
        try
        {
            var encodedName = Uri.EscapeDataString(name);
            var url = $"organisations/search?name={encodedName}&page={page}&pageSize={pageSize}";

            var response = await _httpClient.GetAsync(url);

            if (!response.IsSuccessStatusCode)
            {
                return null;
            }

            return await response.Content.ReadFromJsonAsync<SraOrganisationSearchResponse>(JsonOptions);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error searching SRA for organisation: {Name}", name);
            return null;
        }
    }

    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNameCaseInsensitive = true,
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
    };
}

// Response models
public class SraSolicitorSearchResponse
{
    public List<SraSolicitorSearchItem>? Results { get; set; }
    public int TotalCount { get; set; }
    public int Page { get; set; }
    public int PageSize { get; set; }
}

public class SraSolicitorSearchItem
{
    public string? SraId { get; set; }
    public string? Name { get; set; }
    public string? Status { get; set; }
    public string? Town { get; set; }
    public string? AdmissionDate { get; set; }
    public string? CurrentOrganisation { get; set; }
}

public class SraSolicitorDetails
{
    public string? SraId { get; set; }
    public string? Forename { get; set; }
    public string? MiddleNames { get; set; }
    public string? Surname { get; set; }
    public string? Status { get; set; }
    public string? AdmissionDate { get; set; }
    public string? SolicitorType { get; set; }
    public string? PractisingCertificateStatus { get; set; }

    public SraCurrentPosition? CurrentPosition { get; set; }
    public List<SraPreviousPosition>? PreviousPositions { get; set; }
    public List<SraDisciplinaryRecord>? DisciplinaryHistory { get; set; }

    public string FullName => string.Join(" ",
        new[] { Forename, MiddleNames, Surname }.Where(s => !string.IsNullOrWhiteSpace(s)));
}

public class SraCurrentPosition
{
    public string? OrganisationName { get; set; }
    public string? OrganisationSraId { get; set; }
    public string? Role { get; set; }
    public string? StartDate { get; set; }
}

public class SraPreviousPosition
{
    public string? OrganisationName { get; set; }
    public string? OrganisationSraId { get; set; }
    public string? Role { get; set; }
    public string? StartDate { get; set; }
    public string? EndDate { get; set; }
}

public class SraDisciplinaryRecord
{
    public string? DecisionDate { get; set; }
    public string? DecisionType { get; set; }
    public string? Summary { get; set; }
}

public class SraOrganisationSearchResponse
{
    public List<SraOrganisationSearchItem>? Results { get; set; }
    public int TotalCount { get; set; }
}

public class SraOrganisationSearchItem
{
    public string? SraId { get; set; }
    public string? Name { get; set; }
    public string? Status { get; set; }
    public string? Type { get; set; }
    public string? Town { get; set; }
}
