using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Электронная_Фармация.Classes
{
public class ApiClient
{
private readonly HttpClient _httpClient;
private readonly string _baseUrl;
private string _token;
public ApiClient(string baseUrl = null)
{
_baseUrl = (baseUrl ?? AppConfig.ApiBaseUrl).TrimEnd('/');
_httpClient = new HttpClient
{
BaseAddress = new Uri(_baseUrl),
Timeout = TimeSpan.FromSeconds(30)
};
}
///
/// Выполняет авторизацию и сохраняет токен
///
/// Имя пользователя
/// Пароль
/// JWT токен
/// При ошибке авторизации
public async Task LoginAsync(string username, string password)
{
var request = new LoginRequest
{
Username = username,
Password = password
};
try
{
var response = await _httpClient.PostAsJsonAsync("/auth/login", request);
if (response.IsSuccessStatusCode)
{
var loginResponse = await response.Content.ReadFromJsonAsync();
_token = loginResponse.Token;
return _token;
}
else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
var error = await response.Content.ReadFromJsonAsync();
throw new UnauthorizedAccessException($"Ошибка авторизации: {error?.Error ?? "Неверные учетные данные"}");
}
else
{
var error = await response.Content.ReadFromJsonAsync();
throw new HttpRequestException($"Ошибка HTTP {response.StatusCode}: {error?.Error ?? "Неизвестная ошибка"}");
}
}
catch (TaskCanceledException)
{
throw new HttpRequestException("Превышено время ожидания ответа сервера");
}
}
///
/// Устанавливает токен для последующих запросов
///
public void SetToken(string token)
{
_token = token;
}
public string Token => _token;
///
/// Проверяет, авторизован ли клиент
///
public bool IsAuthenticated => !string.IsNullOrEmpty(_token);
public async Task GetPriceSummaryAsync(string supplierId = null, string regionId = null)
{
if (!IsAuthenticated)
{
throw new InvalidOperationException("Необходимо выполнить авторизацию перед запросом данных");
}
var queryParams = new List();
if (!string.IsNullOrEmpty(supplierId))
{
queryParams.Add($"supplier_id={Uri.EscapeDataString(supplierId)}");
}
if (!string.IsNullOrEmpty(regionId))
{
queryParams.Add($"region_id={Uri.EscapeDataString(regionId)}");
}
var url = "/api/supplier-prices/summary";
if (queryParams.Count > 0)
{
url += "?" + string.Join("&", queryParams);
}
_httpClient.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _token);
try
{
var response = await _httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var summary = await response.Content.ReadFromJsonAsync();
return summary;
}
else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
_token = null; // Токен истек или невалиден
var error = await response.Content.ReadFromJsonAsync();
throw new UnauthorizedAccessException($"Сессия истекла: {error?.Error ?? "Необходимо войти заново"}");
}
else
{
var error = await response.Content.ReadFromJsonAsync();
throw new HttpRequestException($"Ошибка HTTP {response.StatusCode}: {error?.Error ?? "Неизвестная ошибка"}");
}
}
catch (TaskCanceledException)
{
throw new HttpRequestException("Превышено время ожидания ответа сервера (таймаут 30 секунд)");
}
}
public async Task> GetInvoicesAsync()
{
if (!IsAuthenticated)
{
throw new InvalidOperationException("Необходимо выполнить авторизацию перед запросом накладных");
}
_httpClient.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _token);
var response = await _httpClient.GetAsync("/api/buyer/invoices");
var body = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(
$"Ошибка загрузки накладных: {(int)response.StatusCode} {response.ReasonPhrase}\n{body}");
}
return JsonSerializer.Deserialize>(body) ?? new List();
}
}
public sealed class InvoiceApiItem
{
public string InvoiceNumber { get; set; }
public string InvoiceDate { get; set; }
public string SupplierName { get; set; }
public string ConsigneeName { get; set; }
public string InvoiceSum { get; set; }
public string RefuseSum { get; set; }
}
}