using System.Net; using System.Net.Http.Json; using System.Text; using RobotNet10.CustomConfigurationEditor.Models; namespace RobotNet10.CustomConfigurationEditor.Services.API; /// /// Service cho giao tiếp với Config REST API /// public class ConfigApiService(HttpClient httpClient) { private readonly HttpClient _httpClient = httpClient; private readonly string? _baseUrl = httpClient.BaseAddress?.AbsoluteUri; private const string ApiPath = "api/configs"; // ========================================== // CONFIG FILE MANAGEMENT // ========================================== /// /// Lấy tất cả configs (metadata only) /// public async Task> GetAllConfigsAsync(string? search = null) { var url = $"{_baseUrl}{ApiPath}"; if (!string.IsNullOrEmpty(search)) url += $"?search={Uri.EscapeDataString(search)}"; return await _httpClient.GetFromJsonAsync>(url) ?? []; } /// /// Lấy config theo ID /// public async Task GetConfigByIdAsync(Guid id) { return await _httpClient.GetFromJsonAsync($"{_baseUrl}{ApiPath}/{id}"); } /// /// Lấy config theo ConfigType /// public async Task GetConfigByTypeAsync(string configType) { return await _httpClient.GetFromJsonAsync($"{_baseUrl}{ApiPath}/by-type/{Uri.EscapeDataString(configType)}"); } /// /// Kiểm tra ConfigType có tồn tại không /// public async Task ConfigTypeExistsAsync(string configType) { return await _httpClient.GetFromJsonAsync($"{_baseUrl}{ApiPath}/exists/{Uri.EscapeDataString(configType)}"); } /// /// Tạo config mới /// public async Task CreateConfigAsync(string configType, List variables, string? description = null) { var request = new { ConfigType = configType, Variables = variables, Description = description }; var response = await _httpClient.PostAsJsonAsync($"{_baseUrl}{ApiPath}", request); if (!response.IsSuccessStatusCode) { var errorMessage = await HttpErrorHelper.GetErrorMessageAsync(response); throw new HttpRequestException(errorMessage); } return await response.Content.ReadFromJsonAsync() ?? throw new Exception("Failed to create config. Invalid response from server."); } /// /// Cập nhật config /// public async Task UpdateConfigAsync(Guid id, List? variables = null, string? description = null) { var request = new { Variables = variables, Description = description }; var response = await _httpClient.PutAsJsonAsync($"{_baseUrl}{ApiPath}/{id}", request); if (!response.IsSuccessStatusCode) { var errorMessage = await HttpErrorHelper.GetErrorMessageAsync(response); throw new HttpRequestException(errorMessage); } return await response.Content.ReadFromJsonAsync() ?? throw new Exception("Failed to update config. Invalid response from server."); } /// /// Xóa config /// public async Task DeleteConfigAsync(Guid id) { var response = await _httpClient.DeleteAsync($"{_baseUrl}{ApiPath}/{id}"); if (!response.IsSuccessStatusCode) { var errorMessage = await HttpErrorHelper.GetErrorMessageAsync(response); throw new HttpRequestException(errorMessage); } } // ========================================== // IMPORT/EXPORT // ========================================== /// /// Import config từ JSON file /// public async Task ImportConfigAsync(Stream fileStream, string fileName, string configType, string? description = null) { using var content = new MultipartFormDataContent(); var streamContent = new StreamContent(fileStream); streamContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); content.Add(streamContent, "file", fileName); content.Add(new StringContent(configType), "configType"); if (!string.IsNullOrWhiteSpace(description)) { content.Add(new StringContent(description), "description"); } var response = await _httpClient.PostAsync($"{_baseUrl}{ApiPath}/import", content); if (!response.IsSuccessStatusCode) { var errorMessage = await HttpErrorHelper.GetErrorMessageAsync(response); throw new HttpRequestException(errorMessage); } return await response.Content.ReadFromJsonAsync() ?? throw new Exception("Failed to import config. Invalid response from server."); } /// /// Export config ra JSON file /// public async Task ExportConfigAsync(Guid id) { var response = await _httpClient.GetAsync($"{_baseUrl}{ApiPath}/{id}/export"); if (!response.IsSuccessStatusCode) { var errorMessage = await HttpErrorHelper.GetErrorMessageAsync(response); throw new HttpRequestException(errorMessage); } try { // Read content as byte array first, then create memory stream var bytes = await response.Content.ReadAsByteArrayAsync(); var memoryStream = new MemoryStream(bytes); memoryStream.Position = 0; // Reset position to beginning return memoryStream; } catch (Exception ex) { throw new HttpRequestException($"Failed to read export data: {HttpErrorHelper.GetErrorMessage(ex)}", ex); } } // ========================================== // VARIABLE MANAGEMENT // ========================================== /// /// Cập nhật giá trị của một variable /// public async Task UpdateVariableAsync(Guid configId, string variableName, object? value) { var request = new { Value = value }; var response = await _httpClient.PutAsJsonAsync($"{_baseUrl}{ApiPath}/{configId}/variables/{Uri.EscapeDataString(variableName)}", request); if (!response.IsSuccessStatusCode) { var errorMessage = await HttpErrorHelper.GetErrorMessageAsync(response); throw new HttpRequestException(errorMessage); } return await response.Content.ReadFromJsonAsync() ?? throw new Exception("Failed to update variable. Invalid response from server."); } /// /// Thêm variable mới vào config /// public async Task AddVariableAsync(Guid configId, ConfigVariableModel variable) { var response = await _httpClient.PostAsJsonAsync($"{_baseUrl}{ApiPath}/{configId}/variables", variable); if (!response.IsSuccessStatusCode) { var errorMessage = await HttpErrorHelper.GetErrorMessageAsync(response); throw new HttpRequestException(errorMessage); } return await response.Content.ReadFromJsonAsync() ?? throw new Exception("Failed to add variable. Invalid response from server."); } /// /// Xóa variable khỏi config /// public async Task RemoveVariableAsync(Guid configId, string variableName) { var response = await _httpClient.DeleteAsync($"{_baseUrl}{ApiPath}/{configId}/variables/{Uri.EscapeDataString(variableName)}"); if (!response.IsSuccessStatusCode) { var errorMessage = await HttpErrorHelper.GetErrorMessageAsync(response); throw new HttpRequestException(errorMessage); } return await response.Content.ReadFromJsonAsync() ?? throw new Exception("Failed to remove variable. Invalid response from server."); } }