using System.Net.Http.Json;
using System.Text.Json;
using Microsoft.Extensions.Logging;
using RestSharp;

namespace Tr.Sdk;

public class TrClient : ITrClient, IDisposable
{
    private RestClient _client;
    private readonly string _baseUrl;
    private readonly string _apiKey;
    private readonly string _apiSecret;

    public TrClient(string baseUrl, string apiKey, string apiSecret)
    {
        _baseUrl = baseUrl;
        _apiKey = apiKey;
        _apiSecret = apiSecret;
        var options = new RestClientOptions(baseUrl)
        {
            Authenticator = new TrAuthenticator(baseUrl, apiKey, apiSecret)
        };
        _client = new RestClient(options);

    }

    /// <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 : TrRequest
    {
        var req = new RestRequest(request.Path(), request.HttpMethod())
            .AddObject(request);
        try
        {
            var response = await _client.ExecuteAsync<TResponse>(req, cancellationToken);

            if (response?.StatusCode == System.Net.HttpStatusCode.Unauthorized)
            {
                _client.Dispose();
                var options = new RestClientOptions(_baseUrl)
                {
                    Authenticator = new TrAuthenticator(_baseUrl, _apiKey, _apiSecret)
                };
                _client = new RestClient(options);

                response = await _client.ExecuteAsync<TResponse>(req, cancellationToken);
            }

            if (!response?.IsSuccessful ?? false)
                throw new HttpRequestException($"请求呼叫中心服务失败, HttpCode: {response.StatusCode}, Error: {response.ErrorMessage}");

            return response.Data;
        }
        catch (Exception e)
        {
            throw new HttpRequestException($"呼叫中心请求失败，Error: {e.Message}");
        }
    }

    /// <summary>
    /// 执行操作呼叫中心请求
    /// </summary>
    /// <typeparam name="TRequest"></typeparam>
    /// <param name="request"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    /// <exception cref="HttpRequestException"></exception>
    public async Task ExecuteAsync<TRequest>(TRequest request, CancellationToken cancellationToken)
        where TRequest : TrRequest
    {
        var req = new RestRequest(request.Path(), request.HttpMethod())
            .AddObject(request);
        try
        {
            var response = await _client.ExecuteAsync(req, cancellationToken);
            if (!response?.IsSuccessful ?? false)
                throw new HttpRequestException($"请求呼叫中心服务失败, HttpCode: {response.StatusCode}, Error: {response.ErrorMessage}");
        }
        catch (Exception e)
        {
            throw new HttpRequestException($"呼叫中心请求失败，Error: {e.Message}");
        }
    }


    /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
    public void Dispose()
    {
        _client?.Dispose();
        GC.SuppressFinalize(this);
    }
}