using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using Wex.Sdk.Tel;

namespace Wex.Sdk;

public class WexClient : IWexClient
{
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly ITokenManager _tokenManager;

    public WexClient(IHttpClientFactory httpClientFactory, ITokenManager tokenManager)
    {
        _httpClientFactory = httpClientFactory;
        _tokenManager = tokenManager;
    }

    /// <summary>
    /// 执行操作呼叫中心请求
    /// </summary>
    /// <typeparam name="TRequest"></typeparam>
    /// <typeparam name="TResponse"></typeparam>
    /// <param name="request"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public async Task<TResponse?> ExecuteAsync<TRequest, TResponse>(TRequest request, CancellationToken cancellationToken)
        where TRequest : IWexRequest where TResponse : WexResponse
    {
        var httpClient = _httpClientFactory.CreateClient(Defaults.ServiceName);
        var token = await _tokenManager.GetTokenAsync(cancellationToken);
        httpClient.DefaultRequestHeaders.Add("token", token);
        try
        {
            var rsp = await httpClient.PostAsJsonAsync(request.Url, request, cancellationToken: cancellationToken);
            if (!rsp.IsSuccessStatusCode)
                throw new HttpRequestException("请求呼叫中心服务失败");
            var response = await rsp.Content.ReadFromJsonAsync<TResponse>(new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            }, cancellationToken);
            if (response?.Code == 401)
            {
                await _tokenManager.RefreshTokenAsync(cancellationToken);
                response = await rsp.Content.ReadFromJsonAsync<TResponse>(new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
                }, cancellationToken);
            }
            if (response?.Code != 200)
                throw new HttpRequestException(response?.Msg);
            return response;
        }
        catch (Exception)
        {
            throw;
        }
    }

    public async Task<WexToken> GetTokenAsync(TokenRequest request, CancellationToken cancellationToken)
    {
        var httpClient = _httpClientFactory.CreateClient(Defaults.ServiceName);
        try
        {
            var rsp = await httpClient.PostAsJsonAsync(request.Url, request, cancellationToken: cancellationToken);
            if (!rsp.IsSuccessStatusCode)
                throw new HttpRequestException("请求呼叫中心token失败");
            var response = await rsp.Content.ReadFromJsonAsync<WexResponse<WexToken>>(new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            }, cancellationToken);
            if (response.Code != 200)
                throw new HttpRequestException(response.Msg);
            return response.Data;
        }
        catch (Exception e)
        {
            throw;
        }
    }
}