namespace TaxBaik.Web.Services; using System.Net.Http.Json; using TaxBaik.Application.DTOs; using TaxBaik.Domain.Entities; public interface IAnnouncementBrowserClient { Task> GetAllAsync(CancellationToken ct = default); Task GetByIdAsync(int id, CancellationToken ct = default); Task CreateAsync(AnnouncementDto dto, CancellationToken ct = default); Task UpdateAsync(int id, AnnouncementDto dto, CancellationToken ct = default); Task DeleteAsync(int id, CancellationToken ct = default); } public class AnnouncementBrowserClient : IAnnouncementBrowserClient { private readonly HttpClient _http; private readonly ILogger _logger; public AnnouncementBrowserClient(HttpClient http, ILogger logger) { _http = http; _logger = logger; } public async Task> GetAllAsync(CancellationToken ct = default) { try { var result = await _http.GetFromJsonAsync("announcement", cancellationToken: ct); return result?.Data ?? []; } catch (HttpRequestException ex) { _logger.LogError(ex, "Failed to fetch announcements"); throw; } } public async Task GetByIdAsync(int id, CancellationToken ct = default) { try { return await _http.GetFromJsonAsync($"announcement/{id}", cancellationToken: ct); } catch (HttpRequestException ex) { _logger.LogError(ex, "Failed to fetch announcement {AnnouncementId}", id); throw; } } public async Task CreateAsync(AnnouncementDto dto, CancellationToken ct = default) { try { var response = await _http.PostAsJsonAsync("announcement", dto, cancellationToken: ct); if (!response.IsSuccessStatusCode) return null; var content = await response.Content.ReadAsStringAsync(ct); return System.Text.Json.JsonSerializer.Deserialize( content, new System.Text.Json.JsonSerializerOptions { PropertyNameCaseInsensitive = true }); } catch (HttpRequestException ex) { _logger.LogError(ex, "Failed to create announcement"); throw; } } public async Task UpdateAsync(int id, AnnouncementDto dto, CancellationToken ct = default) { try { var response = await _http.PutAsJsonAsync($"announcement/{id}", dto, cancellationToken: ct); if (!response.IsSuccessStatusCode) return null; var content = await response.Content.ReadAsStringAsync(ct); return System.Text.Json.JsonSerializer.Deserialize( content, new System.Text.Json.JsonSerializerOptions { PropertyNameCaseInsensitive = true }); } catch (HttpRequestException ex) { _logger.LogError(ex, "Failed to update announcement {AnnouncementId}", id); throw; } } public async Task DeleteAsync(int id, CancellationToken ct = default) { try { var response = await _http.DeleteAsync($"announcement/{id}", cancellationToken: ct); return response.IsSuccessStatusCode; } catch (HttpRequestException ex) { _logger.LogError(ex, "Failed to delete announcement {AnnouncementId}", id); throw; } } private class AnnouncementListResponse { public List Data { get; set; } = []; } }