namespace TaxBaik.Web.Services.AdminClients; using System.Text.Json; using TaxBaik.Domain.Entities; public interface ITaxProfileBrowserClient { Task> GetAllAsync(CancellationToken ct = default); Task GetByIdAsync(int id, CancellationToken ct = default); Task> GetByClientIdAsync(int clientId, CancellationToken ct = default); Task> GetHighRiskProfilesAsync(CancellationToken ct = default); Task> GetUpcomingFilingDuesAsync(int daysAhead = 30, CancellationToken ct = default); Task CreateAsync(int clientId, string businessType, string? businessRegistration = null, string? accountingMethod = null, DateTime? establishmentDate = null, CancellationToken ct = default); Task UpdateAsync(int id, string? businessType = null, string? accountingMethod = null, DateTime? nextFilingDueDate = null, string? taxRiskLevel = null, CancellationToken ct = default); Task DeleteAsync(int id, CancellationToken ct = default); } public class TaxProfileBrowserClient(HttpClient httpClient, ITokenStore tokenStore, ILogger logger) : ITaxProfileBrowserClient { private const string BaseUrl = "/api/taxprofile"; private void EnsureAuthHeader() { if (!string.IsNullOrEmpty(tokenStore.AccessToken)) httpClient.DefaultRequestHeaders.Authorization = new("Bearer", tokenStore.AccessToken); else httpClient.DefaultRequestHeaders.Authorization = null; } public async Task> GetAllAsync(CancellationToken ct = default) { try { EnsureAuthHeader(); return await httpClient.GetFromJsonAsync>($"{BaseUrl}", ct) ?? []; } catch (Exception ex) { logger.LogError(ex, "Failed to get tax profiles"); return []; } } public async Task GetByIdAsync(int id, CancellationToken ct = default) { try { EnsureAuthHeader(); return await httpClient.GetFromJsonAsync($"{BaseUrl}/{id}", ct); } catch (Exception ex) { logger.LogError(ex, "Failed to get tax profile {Id}", id); return null; } } public async Task> GetByClientIdAsync(int clientId, CancellationToken ct = default) { try { EnsureAuthHeader(); return await httpClient.GetFromJsonAsync>($"{BaseUrl}/client/{clientId}", ct) ?? []; } catch (Exception ex) { logger.LogError(ex, "Failed to get tax profiles for client {ClientId}", clientId); return []; } } public async Task> GetHighRiskProfilesAsync(CancellationToken ct = default) { try { EnsureAuthHeader(); var response = await httpClient.GetFromJsonAsync($"{BaseUrl}/high-risk", ct); if (response.TryGetProperty("data", out var data)) return System.Text.Json.JsonSerializer.Deserialize>(data.GetRawText()) ?? []; return []; } catch (Exception ex) { logger.LogError(ex, "Failed to get high-risk profiles"); return []; } } public async Task> GetUpcomingFilingDuesAsync(int daysAhead = 30, CancellationToken ct = default) { try { EnsureAuthHeader(); var response = await httpClient.GetFromJsonAsync($"{BaseUrl}/upcoming-filings?daysAhead={daysAhead}", ct); if (response.TryGetProperty("data", out var data)) return System.Text.Json.JsonSerializer.Deserialize>(data.GetRawText()) ?? []; return []; } catch (Exception ex) { logger.LogError(ex, "Failed to get upcoming filings"); return []; } } public async Task CreateAsync(int clientId, string businessType, string? businessRegistration = null, string? accountingMethod = null, DateTime? establishmentDate = null, CancellationToken ct = default) { try { EnsureAuthHeader(); var request = new { clientId, businessType, businessRegistration, accountingMethod, establishmentDate }; var response = await httpClient.PostAsJsonAsync(BaseUrl, request, ct); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync(cancellationToken: ct); return result.TryGetProperty("id", out var idProp) ? idProp.GetInt32() : 0; } catch (Exception ex) { logger.LogError(ex, "Failed to create tax profile"); return 0; } } public async Task UpdateAsync(int id, string? businessType = null, string? accountingMethod = null, DateTime? nextFilingDueDate = null, string? taxRiskLevel = null, CancellationToken ct = default) { try { EnsureAuthHeader(); var request = new { businessType, accountingMethod, nextFilingDueDate, taxRiskLevel }; var response = await httpClient.PutAsJsonAsync($"{BaseUrl}/{id}", request, ct); response.EnsureSuccessStatusCode(); } catch (Exception ex) { logger.LogError(ex, "Failed to update tax profile {Id}", id); } } public async Task DeleteAsync(int id, CancellationToken ct = default) { try { EnsureAuthHeader(); var response = await httpClient.DeleteAsync($"{BaseUrl}/{id}", ct); response.EnsureSuccessStatusCode(); } catch (Exception ex) { logger.LogError(ex, "Failed to delete tax profile {Id}", id); } } }