namespace TaxBaik.Web.Client.Components.Admin.Services;

using Microsoft.AspNetCore.Components;
using System.Text.Json;

public interface IApiClient
{
    Task<T?> GetAsync<T>(string endpoint);
    Task<T?> PostAsync<T>(string endpoint, object data);
    Task<T?> PutAsync<T>(string endpoint, object data);
    Task DeleteAsync(string endpoint);
    Task SetAuthToken(string? token);
}

public class ApiClient : IApiClient
{
    private readonly HttpClient _httpClient;
    private readonly NavigationManager _navigationManager;
    private string? _authToken;

    public ApiClient(HttpClient httpClient, NavigationManager navigationManager)
    {
        _httpClient = httpClient;
        _navigationManager = navigationManager;
    }

    public async Task SetAuthToken(string? token)
    {
        _authToken = token;
        if (token != null)
            _httpClient.DefaultRequestHeaders.Authorization = new("Bearer", token);
        else
            _httpClient.DefaultRequestHeaders.Authorization = null;
    }

    public async Task<T?> GetAsync<T>(string endpoint)
    {
        try
        {
            var response = await _httpClient.GetAsync(BuildApiUri(endpoint));
            if (!response.IsSuccessStatusCode)
                return default;

            var content = await response.Content.ReadAsStringAsync();
            return JsonSerializer.Deserialize<T>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
        }
        catch
        {
            return default;
        }
    }

    public async Task<T?> PostAsync<T>(string endpoint, object data)
    {
        try
        {
            var json = JsonSerializer.Serialize(data);
            var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
            var response = await _httpClient.PostAsync(BuildApiUri(endpoint), content);

            if (!response.IsSuccessStatusCode)
                return default;

            var responseContent = await response.Content.ReadAsStringAsync();
            return JsonSerializer.Deserialize<T>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
        }
        catch
        {
            return default;
        }
    }

    public async Task<T?> PutAsync<T>(string endpoint, object data)
    {
        try
        {
            var json = JsonSerializer.Serialize(data);
            var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
            var response = await _httpClient.PutAsync(BuildApiUri(endpoint), content);

            if (!response.IsSuccessStatusCode)
                return default;

            var responseContent = await response.Content.ReadAsStringAsync();
            return JsonSerializer.Deserialize<T>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
        }
        catch
        {
            return default;
        }
    }

    public async Task DeleteAsync(string endpoint)
    {
        try
        {
            await _httpClient.DeleteAsync(BuildApiUri(endpoint));
        }
        catch
        {
            // Ignore
        }
    }

    private Uri BuildApiUri(string endpoint)
    {
        var relative = $"api/{endpoint.TrimStart('/')}";
        var appRoot = new Uri(_navigationManager.BaseUri);
        return new Uri(appRoot, $"/{relative}");
    }
}
