namespace TaxBaik.Web.Services; using System.Net.Http; using System.Net.Http.Json; using TaxBaik.Domain.Entities; /// /// Inquiry API Client for Admin Blazor /// SOLID: Single Responsibility - Inquiry API calls only /// Dependency Inversion - abstraction via interface /// public interface IInquiryBrowserClient { Task<(IEnumerable Items, int Total)> GetPagedAsync(int page = 1, int pageSize = 20, CancellationToken ct = default); Task GetByIdAsync(int id, CancellationToken ct = default); Task UpdateStatusAsync(int id, string status, CancellationToken ct = default); Task UpdateAdminMemoAsync(int id, string adminMemo, CancellationToken ct = default); Task ConvertToClientAsync(int id, string name, string phone, string serviceType, CancellationToken ct = default); } public class InquiryBrowserClient : IInquiryBrowserClient { private readonly HttpClient _http; private readonly ILogger _logger; private readonly ITokenStore _tokenStore; public InquiryBrowserClient(HttpClient http, ILogger logger, ITokenStore tokenStore) { _http = http; _logger = logger; _tokenStore = tokenStore; } private void EnsureAuthHeader() { if (!string.IsNullOrEmpty(_tokenStore.AccessToken)) _http.DefaultRequestHeaders.Authorization = new("Bearer", _tokenStore.AccessToken); else _http.DefaultRequestHeaders.Authorization = null; } public async Task<(IEnumerable Items, int Total)> GetPagedAsync( int page = 1, int pageSize = 20, CancellationToken ct = default) { try { EnsureAuthHeader(); var result = await _http.GetFromJsonAsync( $"inquiry?page={page}&pageSize={pageSize}", cancellationToken: ct); return result != null ? (result.Data, result.Total) : ([], 0); } catch (HttpRequestException ex) { _logger.LogError(ex, "Failed to fetch inquiries"); throw; } } public async Task GetByIdAsync(int id, CancellationToken ct = default) { try { EnsureAuthHeader(); return await _http.GetFromJsonAsync( $"inquiry/{id}", cancellationToken: ct); } catch (HttpRequestException ex) { _logger.LogError(ex, "Failed to fetch inquiry {InquiryId}", id); throw; } } public async Task UpdateStatusAsync(int id, string status, CancellationToken ct = default) { try { EnsureAuthHeader(); var request = new { status }; var response = await _http.PutAsJsonAsync( $"inquiry/{id}/status", request, cancellationToken: ct); return response.IsSuccessStatusCode; } catch (HttpRequestException ex) { _logger.LogError(ex, "Failed to update inquiry {InquiryId} status", id); throw; } } public async Task UpdateAdminMemoAsync(int id, string adminMemo, CancellationToken ct = default) { try { EnsureAuthHeader(); var request = new { adminMemo }; var response = await _http.PutAsJsonAsync( $"inquiry/{id}/memo", request, cancellationToken: ct); return response.IsSuccessStatusCode; } catch (HttpRequestException ex) { _logger.LogError(ex, "Failed to update inquiry {InquiryId} memo", id); throw; } } public async Task ConvertToClientAsync(int id, string name, string phone, string serviceType, CancellationToken ct = default) { try { EnsureAuthHeader(); var response = await _http.PostAsJsonAsync( $"inquiry/{id}/convert-to-client", new { name, phone, serviceType }, cancellationToken: ct); if (!response.IsSuccessStatusCode) return 0; var content = await response.Content.ReadAsStringAsync(ct); var result = System.Text.Json.JsonSerializer.Deserialize( content, new System.Text.Json.JsonSerializerOptions { PropertyNameCaseInsensitive = true }); return result?.ClientId ?? 0; } catch (HttpRequestException ex) { _logger.LogError(ex, "Failed to convert inquiry {InquiryId} to client", id); throw; } } private class InquiryPagedResponse { public List Data { get; set; } = []; public int Total { get; set; } public int Page { get; set; } public int PageSize { get; set; } } private class ConvertToClientResponse { public int ClientId { get; set; } } }