using AShermed.ApiLogCoreFramework.ContractModel;
using AShermed.ApiLogCoreFramework.Service;
using ASHermed.SinoInterface.IFramework.Web;
using ASHermed.SinoInterface.Tools;
using Microsoft.Extensions.Logging;
using PoJun.Util.Webs.Clients;
using Steeltoe.Common.Discovery;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace ASHermed.SinoInterface.BaseFramework
{
    /// <summary>
    /// HttpClientHelp
    /// </summary>
    public class HttpClientHelp : IHttpClientHelp
    {
        #region 初始化

        /// <summary>
        /// 日志服务
        /// </summary>
        private readonly IAPILogService apiLogService;

        /// <summary>
        /// 
        /// </summary>
        private readonly IHttpClientFactory clientFactory;

        /// <summary>
        /// 文本日志
        /// </summary>
        private readonly ILogger<HttpClientHelp> logger;

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="_apiLogService"></param>
        /// <param name="_clientFactory"></param>
        /// <param name="_logger"></param>
        public HttpClientHelp(IAPILogService _apiLogService, IHttpClientFactory _clientFactory, ILogger<HttpClientHelp> _logger)
        {
            apiLogService = _apiLogService;
            clientFactory = _clientFactory;
            logger = _logger;
        }

        #endregion

        #region 下载文件[异步]

        /// <summary>
        /// 下载文件[异步]
        /// </summary>
        /// <param name="url">下载链接地址</param>
        /// <param name="timeout">请求响应超时时间，单位/s(默认100秒)</param>
        /// <returns></returns>
        public async Task<(byte[] Data, string LogId)> DownloadAsync(string url, int timeout = 100)
        {
            #region Http基础设置

            var client = clientFactory.CreateClient("download");
            //设置接口超时时间
            if (timeout > 0)
            {
                client.Timeout = new TimeSpan(0, 0, timeout);
            }

            #endregion

            #region 新增请求日志

            Uri uri = new Uri(url);
            var log_request_param = new AddRequestLogParam
            {
                APIName = uri.PathAndQuery.ToLower(),
                ClientHost = PoJun.Util.Helpers.Web.Ip,
                RequestTime = DateTime.Now,
                ServerHost = $"{uri.Scheme}://{uri.Host}",
                SystemID = SysUtil.GetSystemId(),
                TraceID = PoJun.Util.Helpers.Id.GetGuidBy32(),
                Level = 2,
                ParentTraceID = SysUtil.GetTraceId(),
                RequestBody = null
            };
            if (SysUtil.GetTraceId() != null)
            {
                log_request_param.Level = 2;
                log_request_param.ParentTraceID = SysUtil.GetTraceId();
            }
            else
            {
                log_request_param.Level = 1;
            }
            try
            {
                await apiLogService.AddRequestLogAsync(log_request_param);
            }
            catch (System.Exception)
            {
                //记录文本日志
                logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_request_param)},");
            }

            #endregion

            #region 发起Http请求

            System.Exception exs = null;
            Byte[] resultBytes = null;

            try
            {
                //异步发送请求
                resultBytes = await client.GetByteArrayAsync(url);
                if (resultBytes == null || !resultBytes.Any())
                    return (resultBytes, log_request_param.TraceID);

            }
            catch (System.Exception ex)
            {
                exs = ex;
            }
            finally
            {
                #region 新增响应日志

                var log_response_param = new AddResponseLogParam
                {
                    IsError = false,
                    ResponseBody = "由于数据量太大被替换了！！！",
                    ResponseTime = DateTime.Now,
                    ParentTraceID = log_request_param.TraceID
                };
                log_response_param.TimeCost = Convert.ToInt32((log_response_param.ResponseTime - log_request_param.RequestTime).TotalMilliseconds);
                if ((resultBytes == null || resultBytes.Count() == 0) && exs != null)
                    log_response_param.ErrorBody = $"Message：{exs.Message} | StackTrace: {exs.StackTrace} | Source: {exs.Source} | InnerException： {exs.InnerException?.ToString()}";
                try
                {
                    await apiLogService.AddResponseLogAsync(log_response_param);
                }
                catch (System.Exception)
                {
                    logger.LogWarning($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_response_param)},");
                }

                #endregion
            }

            #endregion

            #region 返回结果

            return (resultBytes, log_request_param.TraceID);

            #endregion
        }

        #endregion

        #region 下载文件[同步]

        /// <summary>
        /// 下载文件[同步]
        /// </summary>
        /// <param name="url">下载链接地址</param>
        /// <param name="timeout">请求响应超时时间，单位/s(默认100秒)</param>
        /// <returns></returns>
        public (byte[] Data, string LogId) Download(string url, int timeout = 100)
        {
            #region Http基础设置

            var client = clientFactory.CreateClient("download");
            //设置接口超时时间
            if (timeout > 0)
            {
                client.Timeout = new TimeSpan(0, 0, timeout);
            }

            #endregion

            #region 新增请求日志

            Uri uri = new Uri(url);
            var log_request_param = new AddRequestLogParam
            {
                APIName = uri.PathAndQuery.ToLower(),
                ClientHost = PoJun.Util.Helpers.Web.Ip,
                RequestTime = DateTime.Now,
                ServerHost = $"{uri.Scheme}://{uri.Host}",
                SystemID = SysUtil.GetSystemId(),
                TraceID = PoJun.Util.Helpers.Id.GetGuidBy32(),
                Level = 2,
                ParentTraceID = SysUtil.GetTraceId(),
                RequestBody = null
            };
            if (SysUtil.GetTraceId() != null)
            {
                log_request_param.Level = 2;
                log_request_param.ParentTraceID = SysUtil.GetTraceId();
            }
            else
            {
                log_request_param.Level = 1;
            }
            try
            {
                apiLogService.AddRequestLogAsync(log_request_param).Wait();
            }
            catch (System.Exception)
            {
                //记录文本日志
                logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_request_param)},");
            }

            #endregion

            #region 发起Http请求

            System.Exception exs = null;
            Byte[] resultBytes = null;

            try
            {
                //异步发送请求
                resultBytes = client.GetByteArrayAsync(url).Result;
                if (resultBytes == null || resultBytes.Count() == 0 || !resultBytes.Any())
                    return (resultBytes, log_request_param.TraceID);
            }
            catch (System.Exception ex)
            {
                exs = ex;
            }
            finally
            {
                #region 新增响应日志

                var log_response_param = new AddResponseLogParam
                {
                    IsError = false,
                    ResponseBody = "由于数据量太大被替换了！！！",
                    ResponseTime = DateTime.Now,
                    ParentTraceID = log_request_param.TraceID
                };
                log_response_param.TimeCost = Convert.ToInt32((log_response_param.ResponseTime - log_request_param.RequestTime).TotalMilliseconds);
                if ((resultBytes == null || resultBytes.Count() == 0) && exs != null)
                    log_response_param.ErrorBody = $"Message：{exs.Message} | StackTrace: {exs.StackTrace} | Source: {exs.Source} | InnerException： {exs.InnerException?.ToString()}";
                try
                {
                    apiLogService.AddResponseLogAsync(log_response_param).Wait();
                }
                catch (System.Exception)
                {
                    logger.LogWarning($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_response_param)},");
                }

                #endregion
            }

            #endregion

            #region 返回结果

            return (resultBytes, log_request_param.TraceID);

            #endregion
        }

        #endregion

        #region GET请求[同步]

        /// <summary>
        /// GET请求[同步]
        /// </summary>
        /// <typeparam name="T">只能传入DTO对象</typeparam>
        /// <param name="host">域名</param>
        /// <param name="apiName">接口名称(接口地址)</param>
        /// <param name="headers">请求头</param>
        /// <param name="timeout">请求响应超时时间，单位/s(默认100秒)</param>
        /// <param name="authorization">身份认证</param>
        /// <returns></returns>
        public (T Data, string LogId) HttpGet<T>(string host, string apiName, Dictionary<string, string> headers = null, int timeout = 100, Dictionary<string, string> authorization = null)
        {
            var client = clientFactory.CreateClient("base");
            {
                #region Http基础设置

                //设置HTTP请求头
                if (headers != null)
                {
                    foreach (KeyValuePair<string, string> header in headers)
                    {
                        client.DefaultRequestHeaders.Add(header.Key, header.Value);
                    }
                }
                //设置接口超时时间
                if (timeout > 0)
                {
                    client.Timeout = new TimeSpan(0, 0, timeout);
                }
                //身份认证
                if (authorization != null)
                {
                    foreach (var item in authorization)
                    {
                        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(item.Key, item.Value);
                    }
                }

                #endregion

                #region 新增请求日志

                var log_request_param = new AddRequestLogParam
                {
                    APIName = apiName.ToString().ToLower(),
                    ClientHost = PoJun.Util.Helpers.Web.Ip,
                    RequestTime = DateTime.Now,
                    ServerHost = host,
                    SystemID = SysUtil.GetSystemId(),
                    TraceID = PoJun.Util.Helpers.Id.GetGuidBy32(),
                    Level = 2,
                    ParentTraceID = SysUtil.GetTraceId(),
                    RequestBody = null
                };
                if (SysUtil.GetTraceId() != null)
                {
                    log_request_param.Level = 2;
                    log_request_param.ParentTraceID = SysUtil.GetTraceId();
                }
                else
                {
                    log_request_param.Level = 1;
                }
                try
                {
                    apiLogService.AddRequestLogAsync(log_request_param).Wait();
                }
                catch (System.Exception)
                {
                    //记录文本日志
                    logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_request_param)},");
                }

                #endregion

                #region 发起Http请求

                var url = $"{host}{apiName}";
                var result = string.Empty;

                System.Exception exs = null;

                try
                {
                    //异步发送请求
                    Byte[] resultBytes = client.GetByteArrayAsync(url).Result;
                    if (resultBytes == null || !resultBytes.Any())
                        return (default(T), log_request_param.TraceID);
                    result = Encoding.UTF8.GetString(resultBytes);

                }
                catch (System.Exception ex)
                {
                    exs = ex;
                }
                finally
                {
                    #region 新增响应日志

                    var log_response_param = new AddResponseLogParam
                    {
                        IsError = false,
                        ResponseBody = result,
                        ResponseTime = DateTime.Now,
                        ParentTraceID = log_request_param.TraceID
                    };
                    log_response_param.TimeCost = Convert.ToInt32((log_response_param.ResponseTime - log_request_param.RequestTime).TotalMilliseconds);
                    if (string.IsNullOrEmpty(result) && exs != null)
                        log_response_param.ErrorBody = $"Message：{exs.Message} | StackTrace: {exs.StackTrace} | Source: {exs.Source} | InnerException： {exs.InnerException?.ToString()}";
                    try
                    {
                        apiLogService.AddResponseLogAsync(log_response_param).Wait();
                    }
                    catch (System.Exception)
                    {
                        logger.LogWarning($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_response_param)},");
                    }

                    #endregion
                }

                #endregion

                #region 返回结果

                if (string.IsNullOrEmpty(result))
                    return (default(T), log_request_param.TraceID);
                return (Newtonsoft.Json.JsonConvert.DeserializeObject<T>(result), log_request_param.TraceID);

                #endregion
            }
        }

        /// <summary>
        /// GET请求[同步]
        /// </summary>
        /// <param name="host">域名</param>
        /// <param name="apiName">接口名称(接口地址)</param>
        /// <param name="headers">请求头</param>
        /// <param name="timeout">请求响应超时时间，单位/s(默认100秒)</param>
        /// <param name="authorization">身份认证</param>
        /// <returns></returns>
        public (string Data, string LogId) HttpGet(string host, string apiName, Dictionary<string, string> headers = null, int timeout = 0, Dictionary<string, string> authorization = null)
        {
            var client = clientFactory.CreateClient("base");
            {
                #region Http基础设置

                //设置HTTP请求头
                if (headers != null)
                {
                    foreach (KeyValuePair<string, string> header in headers)
                    {
                        client.DefaultRequestHeaders.Add(header.Key, header.Value);
                    }
                }
                //设置接口超时时间
                if (timeout > 0)
                {
                    client.Timeout = new TimeSpan(0, 0, timeout);
                }
                //身份认证
                if (authorization != null)
                {
                    foreach (var item in authorization)
                    {
                        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(item.Key, item.Value);
                    }
                }

                #endregion

                #region 新增请求日志

                var log_request_param = new AddRequestLogParam
                {
                    APIName = apiName.ToString().ToLower(),
                    ClientHost = PoJun.Util.Helpers.Web.Ip,
                    RequestTime = DateTime.Now,
                    ServerHost = host,
                    SystemID = SysUtil.GetSystemId(),
                    TraceID = PoJun.Util.Helpers.Id.GetGuidBy32(),
                    Level = 2,
                    ParentTraceID = SysUtil.GetTraceId(),
                    RequestBody = null
                };
                if (SysUtil.GetTraceId() != null)
                {
                    log_request_param.Level = 2;
                    log_request_param.ParentTraceID = SysUtil.GetTraceId();
                }
                else
                {
                    log_request_param.Level = 1;
                }
                try
                {
                    var log_request_result = apiLogService.AddRequestLogAsync(log_request_param).Result;
                }
                catch (System.Exception)
                {
                    //记录文本日志
                    logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_request_param)},");
                }

                #endregion

                #region 发起Http请求

                var url = $"{host}{apiName}";
                var result = string.Empty;

                System.Exception exs = null;

                try
                {
                    //异步发送请求
                    Byte[] resultBytes = client.GetByteArrayAsync(url).Result;
                    if (resultBytes == null || !resultBytes.Any())
                        return (null, log_request_param.TraceID);
                    result = Encoding.UTF8.GetString(resultBytes);

                }
                catch (System.Exception ex)
                {
                    exs = ex;
                }
                finally
                {
                    #region 新增响应日志

                    var log_response_param = new AddResponseLogParam
                    {
                        IsError = false,
                        ResponseBody = result,
                        ResponseTime = DateTime.Now,
                        ParentTraceID = log_request_param.TraceID
                    };
                    log_response_param.TimeCost = Convert.ToInt32((log_response_param.ResponseTime - log_request_param.RequestTime).TotalMilliseconds);
                    if (string.IsNullOrEmpty(result) && exs != null)
                        log_response_param.ErrorBody = $"Message：{exs.Message} | StackTrace: {exs.StackTrace} | Source: {exs.Source} | InnerException： {exs.InnerException?.ToString()}";
                    try
                    {
                        apiLogService.AddResponseLogAsync(log_response_param).Wait();
                    }
                    catch (System.Exception)
                    {
                        //记录文本日志
                        logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_response_param)},");
                    }

                    #endregion
                }

                #endregion

                #region 返回结果

                return (result, log_request_param.TraceID);

                #endregion
            }
        }

        #endregion

        #region GET请求[异步]

        /// <summary>
        /// GET请求[异步]
        /// </summary>
        /// <typeparam name="T">只能传入DTO对象</typeparam>
        /// <param name="host">域名</param>
        /// <param name="apiName">接口名称(接口地址)</param>
        /// <param name="headers">请求头</param>
        /// <param name="timeout">请求响应超时时间，单位/s(默认100秒)</param>
        /// <param name="authorization">身份认证</param>
        /// <returns></returns>
        public async Task<(T Data, string LogId)> HttpGetAsync<T>(string host, string apiName, Dictionary<string, string> headers = null, int timeout = 100, Dictionary<string, string> authorization = null)
        {
            var client = clientFactory.CreateClient("base");
            {
                #region Http基础设置

                //设置HTTP请求头
                if (headers != null)
                {
                    foreach (KeyValuePair<string, string> header in headers)
                    {
                        client.DefaultRequestHeaders.Add(header.Key, header.Value);
                    }
                }
                //设置接口超时时间
                if (timeout > 0)
                {
                    client.Timeout = new TimeSpan(0, 0, timeout);
                }
                //身份认证
                if (authorization != null)
                {
                    foreach (var item in authorization)
                    {
                        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(item.Key, item.Value);
                    }
                }

                #endregion

                #region 新增请求日志

                var log_request_param = new AddRequestLogParam
                {
                    APIName = apiName.ToString().ToLower(),
                    ClientHost = PoJun.Util.Helpers.Web.Ip,
                    RequestTime = DateTime.Now,
                    ServerHost = host,
                    SystemID = SysUtil.GetSystemId(),
                    TraceID = PoJun.Util.Helpers.Id.GetGuidBy32(),
                    Level = 2,
                    ParentTraceID = SysUtil.GetTraceId(),
                    RequestBody = null
                };
                if (SysUtil.GetTraceId() != null)
                {
                    log_request_param.Level = 2;
                    log_request_param.ParentTraceID = SysUtil.GetTraceId();
                }
                else
                {
                    log_request_param.Level = 1;
                }
                try
                {
                    await apiLogService.AddRequestLogAsync(log_request_param);
                }
                catch (System.Exception)
                {
                    //记录文本日志
                    logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_request_param)},");
                }

                #endregion

                #region 发起Http请求

                var url = $"{host}{apiName}";
                var result = string.Empty;

                System.Exception exs = null;

                try
                {
                    //异步发送请求
                    Byte[] resultBytes = await client.GetByteArrayAsync(url);
                    if (resultBytes == null || !resultBytes.Any())
                        return (default(T), log_request_param.TraceID);
                    result = Encoding.UTF8.GetString(resultBytes);

                }
                catch (System.Exception ex)
                {
                    exs = ex;
                }
                finally
                {
                    #region 新增响应日志

                    var log_response_param = new AddResponseLogParam
                    {
                        IsError = false,
                        ResponseBody = result,
                        ResponseTime = DateTime.Now,
                        ParentTraceID = log_request_param.TraceID
                    };
                    log_response_param.TimeCost = Convert.ToInt32((log_response_param.ResponseTime - log_request_param.RequestTime).TotalMilliseconds);
                    if (string.IsNullOrEmpty(result) && exs != null)
                        log_response_param.ErrorBody = $"Message：{exs.Message} | StackTrace: {exs.StackTrace} | Source: {exs.Source} | InnerException： {exs.InnerException?.ToString()}";
                    try
                    {
                        await apiLogService.AddResponseLogAsync(log_response_param);
                    }
                    catch (System.Exception)
                    {
                        //记录文本日志
                        logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_response_param)},");
                    }

                    #endregion
                }

                #endregion

                #region 返回结果

                if (string.IsNullOrEmpty(result))
                    return (default(T), log_request_param.TraceID);
                return (Newtonsoft.Json.JsonConvert.DeserializeObject<T>(result), log_request_param.TraceID);

                #endregion
            }
        }

        /// <summary>
        /// GET请求[异步]
        /// </summary>
        /// <param name="host">域名</param>
        /// <param name="apiName">接口名称(接口地址)</param>
        /// <param name="headers">请求头</param>
        /// <param name="timeout">请求响应超时时间，单位/s(默认100秒)</param>
        /// <param name="authorization">身份认证</param>
        /// <returns></returns>
        public async Task<(string Data, string LogId)> HttpGetAsync(string host, string apiName, Dictionary<string, string> headers = null, int timeout = 0, Dictionary<string, string> authorization = null)
        {
            var client = clientFactory.CreateClient("base");
            {
                #region Http基础设置

                //设置HTTP请求头
                if (headers != null)
                {
                    foreach (KeyValuePair<string, string> header in headers)
                    {
                        client.DefaultRequestHeaders.Add(header.Key, header.Value);
                    }
                }
                //设置接口超时时间
                if (timeout > 0)
                {
                    client.Timeout = new TimeSpan(0, 0, timeout);
                }

                //身份认证
                if (authorization != null)
                {
                    foreach (var item in authorization)
                    {
                        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(item.Key, item.Value);
                    }
                }

                #endregion

                #region 新增请求日志

                var log_request_param = new AddRequestLogParam
                {
                    APIName = apiName.ToString().ToLower(),
                    ClientHost = PoJun.Util.Helpers.Web.Ip,
                    RequestTime = DateTime.Now,
                    ServerHost = host,
                    SystemID = SysUtil.GetSystemId(),
                    TraceID = PoJun.Util.Helpers.Id.GetGuidBy32(),
                    Level = 2,
                    ParentTraceID = SysUtil.GetTraceId(),
                    RequestBody = null
                };
                if (SysUtil.GetTraceId() != null)
                {
                    log_request_param.Level = 2;
                    log_request_param.ParentTraceID = SysUtil.GetTraceId();
                }
                else
                {
                    log_request_param.Level = 1;
                }
                try
                {
                    await apiLogService.AddRequestLogAsync(log_request_param);
                }
                catch (System.Exception)
                {
                    //记录文本日志
                    logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_request_param)},");
                }

                #endregion

                #region 发起Http请求

                var url = $"{host}{apiName}";
                var result = string.Empty;

                System.Exception exs = null;

                try
                {
                    //异步发送请求
                    Byte[] resultBytes = await client.GetByteArrayAsync(url);
                    if (resultBytes == null || !resultBytes.Any())
                        return (null, log_request_param.TraceID);
                    result = Encoding.UTF8.GetString(resultBytes);

                }
                catch (System.Exception ex)
                {
                    exs = ex;
                }
                finally
                {
                    #region 新增响应日志

                    var log_response_param = new AddResponseLogParam
                    {
                        IsError = false,
                        ResponseBody = result,
                        ResponseTime = DateTime.Now,
                        ParentTraceID = log_request_param.TraceID
                    };
                    log_response_param.TimeCost = Convert.ToInt32((log_response_param.ResponseTime - log_request_param.RequestTime).TotalMilliseconds);
                    if (string.IsNullOrEmpty(result) && exs != null)
                        log_response_param.ErrorBody = $"Message：{exs.Message} | StackTrace: {exs.StackTrace} | Source: {exs.Source} | InnerException： {exs.InnerException?.ToString()}";
                    try
                    {
                        await apiLogService.AddResponseLogAsync(log_response_param);
                    }
                    catch (System.Exception)
                    {
                        //记录文本日志
                        logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_response_param)},");
                    }

                    #endregion
                }

                #endregion

                #region 返回结果

                return (result, log_request_param.TraceID);

                #endregion
            }
        }

        #endregion

        #region Post请求[同步]

        /// <summary>
        /// Post请求[同步]
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="host">域名</param>
        /// <param name="apiName">接口名称(接口地址)</param>
        /// <param name="dicParameters">接口参数</param>
        /// <param name="headers">请求头</param>
        /// <param name="timeout">请求响应超时时间，单位/s(默认100秒)</param>
        /// <param name="contentType">请求类型</param>
        /// <param name="isMultilevelNestingJson">是否为多层嵌套json</param>
        /// <param name="authorization">身份认证</param>
        /// <returns></returns>
        public (T Data, string LogId) HttpPost<T>(string host, string apiName, IDictionary<string, string> dicParameters, Dictionary<string, string> headers = null, int timeout = 100, HttpContentType contentType = HttpContentType.Json, bool isMultilevelNestingJson = false, Dictionary<string, string> authorization = null)
        {
            var client = clientFactory.CreateClient("base");
            {
                #region Http基础设置

                //设置接口超时时间
                if (timeout > 0)
                {
                    client.Timeout = new TimeSpan(0, 0, timeout);
                }
                //身份认证
                if (authorization != null)
                {
                    foreach (var item in authorization)
                    {
                        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(item.Key, item.Value);
                    }
                }

                var _contentType = (contentType == HttpContentType.Json ? "application/json" : "application/x-www-form-urlencoded");
                HttpContent content;
                if (contentType == HttpContentType.Json)
                {
                    if (isMultilevelNestingJson)
                        content = new StringContent(dicParameters["json"]);
                    else
                        content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(dicParameters));
                }
                else
                {
                    content = new FormUrlEncodedContent(dicParameters);
                }
                content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(_contentType);
                //设置HTTP请求头
                if (headers != null)
                {
                    foreach (KeyValuePair<string, string> header in headers)
                    {
                        content.Headers.Add(header.Key, header.Value);
                    }
                }

                #endregion

                #region 新增请求日志

                var log_request_param = new AddRequestLogParam
                {
                    APIName = apiName.ToString().ToLower(),
                    ClientHost = PoJun.Util.Helpers.Web.Ip,
                    RequestTime = DateTime.Now,
                    ServerHost = host,
                    SystemID = SysUtil.GetSystemId(),
                    TraceID = PoJun.Util.Helpers.Id.GetGuidBy32(),
                    Level = 2,
                    ParentTraceID = SysUtil.GetTraceId(),
                    RequestBody = Newtonsoft.Json.JsonConvert.SerializeObject(dicParameters)
                };
                if (SysUtil.GetTraceId() != null)
                {
                    log_request_param.Level = 2;
                    log_request_param.ParentTraceID = SysUtil.GetTraceId();
                }
                else
                {
                    log_request_param.Level = 1;
                }
                try
                {
                    apiLogService.AddRequestLogAsync(log_request_param).Wait();
                }
                catch (System.Exception)
                {
                    //记录文本日志
                    logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_request_param)},");
                }

                #endregion

                #region 发起Http请求

                var url = $"{host}{apiName}";
                var strResult = string.Empty;
                HttpResponseMessage events = null;
                System.Exception exs = null;

                try
                {
                    //异步发送请求
                    events = client.PostAsync(url, content).Result;
                    if (events != null && events.IsSuccessStatusCode)
                        //异步获取请求的结果
                        strResult = events.Content.ReadAsStringAsync().Result;
                }
                catch (System.Exception ex)
                {
                    exs = ex;
                }
                finally
                {
                    #region 新增响应日志

                    var log_response_param = new AddResponseLogParam
                    {
                        IsError = false,
                        ResponseBody = strResult,
                        ResponseTime = DateTime.Now,
                        ParentTraceID = log_request_param.TraceID
                    };
                    log_response_param.TimeCost = Convert.ToInt32((log_response_param.ResponseTime - log_request_param.RequestTime).TotalMilliseconds);
                    if (events != null)
                        log_response_param.ErrorBody = $"StatusCode：{events.StatusCode} | events: {Newtonsoft.Json.JsonConvert.SerializeObject(events)}";
                    else
                        log_response_param.ErrorBody = $"Message：{exs.Message} | StackTrace: {exs.StackTrace} | Source: {exs.Source} | InnerException： {exs.InnerException?.ToString()}";
                    try
                    {
                        apiLogService.AddResponseLogAsync(log_response_param).Wait();
                    }
                    catch (System.Exception)
                    {
                        //记录文本日志
                        logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_response_param)},");
                    }

                    #endregion
                }

                #endregion

                #region 返回结果

                if (string.IsNullOrEmpty(strResult))
                    return (default(T), log_request_param.TraceID);
                return (Newtonsoft.Json.JsonConvert.DeserializeObject<T>(strResult), log_request_param.TraceID);

                #endregion
            }
        }

        /// <summary>
        /// Post请求[同步]
        /// </summary>
        /// <param name="host">域名</param>
        /// <param name="apiName">接口名称(接口地址)</param>
        /// <param name="dicParameters">接口参数</param>
        /// <param name="headers">请求头</param>
        /// <param name="timeout">请求响应超时时间，单位/s(默认100秒)</param>
        /// <param name="contentType">请求类型</param>
        /// <param name="isMultilevelNestingJson">是否为多层嵌套json</param>
        /// <param name="authorization">身份认证</param>
        /// <returns></returns>
        public (string Data, string LogId) HttpPost(string host, string apiName, IDictionary<string, string> dicParameters, Dictionary<string, string> headers = null, int timeout = 100, HttpContentType contentType = HttpContentType.Json, bool isMultilevelNestingJson = false, Dictionary<string, string> authorization = null)
        {
            var client = clientFactory.CreateClient("base");
            {
                #region Http基础设置

                //设置接口超时时间
                if (timeout > 0)
                {
                    client.Timeout = new TimeSpan(0, 0, timeout);
                }
                //身份认证
                if (authorization != null)
                {
                    foreach (var item in authorization)
                    {
                        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(item.Key, item.Value);
                    }
                }

                var _contentType = (contentType == HttpContentType.Json ? "application/json" : "application/x-www-form-urlencoded");
                HttpContent content;
                if (contentType == HttpContentType.Json)
                {
                    if (isMultilevelNestingJson)
                        content = new StringContent(dicParameters["json"]);
                    else
                        content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(dicParameters));
                }
                else
                {
                    content = new FormUrlEncodedContent(dicParameters);
                }
                content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(_contentType);
                //设置HTTP请求头
                if (headers != null)
                {
                    foreach (KeyValuePair<string, string> header in headers)
                    {
                        content.Headers.Add(header.Key, header.Value);
                    }
                }

                #endregion

                #region 新增请求日志

                var log_request_param = new AddRequestLogParam
                {
                    APIName = apiName.ToString().ToLower(),
                    ClientHost = PoJun.Util.Helpers.Web.Ip,
                    RequestTime = DateTime.Now,
                    ServerHost = host,
                    SystemID = SysUtil.GetSystemId(),
                    TraceID = PoJun.Util.Helpers.Id.GetGuidBy32(),
                    Level = 2,
                    ParentTraceID = SysUtil.GetTraceId(),
                    RequestBody = Newtonsoft.Json.JsonConvert.SerializeObject(dicParameters)
                };
                if (SysUtil.GetTraceId() != null)
                {
                    log_request_param.Level = 2;
                    log_request_param.ParentTraceID = SysUtil.GetTraceId();
                }
                else
                {
                    log_request_param.Level = 1;
                }
                try
                {
                    apiLogService.AddRequestLogAsync(log_request_param).Wait();
                }
                catch (System.Exception)
                {
                    //记录文本日志
                    logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_request_param)},");
                }

                #endregion

                #region 发起Http请求

                var url = $"{host}{apiName}";
                var strResult = string.Empty;
                HttpResponseMessage events = null;
                System.Exception exs = null;

                try
                {
                    //异步发送请求
                    events = client.PostAsync(url, content).Result;
                    if (events != null && events.IsSuccessStatusCode)
                        //异步获取请求的结果
                        strResult = events.Content.ReadAsStringAsync().Result;
                }
                catch (System.Exception ex)
                {
                    exs = ex;
                }
                finally
                {
                    #region 新增响应日志

                    var log_response_param = new AddResponseLogParam
                    {
                        IsError = false,
                        ResponseBody = strResult,
                        ResponseTime = DateTime.Now,
                        ParentTraceID = log_request_param.TraceID
                    };
                    log_response_param.TimeCost = Convert.ToInt32((log_response_param.ResponseTime - log_request_param.RequestTime).TotalMilliseconds);
                    if (events != null)
                        log_response_param.ErrorBody = $"StatusCode：{events.StatusCode} | events: {Newtonsoft.Json.JsonConvert.SerializeObject(events)}";
                    else
                        log_response_param.ErrorBody = $"Message：{exs.Message} | StackTrace: {exs.StackTrace} | Source: {exs.Source} | InnerException： {exs.InnerException?.ToString()}";
                    try
                    {
                        apiLogService.AddResponseLogAsync(log_response_param).Wait();
                    }
                    catch (System.Exception)
                    {
                        //记录文本日志
                        logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_response_param)},");
                    }

                    #endregion
                }

                #endregion

                #region 返回结果

                return (strResult, log_request_param.TraceID);

                #endregion
            }
        }

        #endregion

        #region Post请求[异步]

        /// <summary>
        /// Post请求[异步]
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="host">域名</param>
        /// <param name="apiName">接口名称(接口地址)</param>
        /// <param name="dicParameters">接口参数</param>
        /// <param name="headers">请求头</param>
        /// <param name="timeout">请求响应超时时间，单位/s(默认100秒)</param>
        /// <param name="contentType">请求类型</param>
        /// <param name="isMultilevelNestingJson">是否为多层嵌套json</param>
        /// <param name="authorization">身份认证</param>
        /// <returns></returns>
        public async Task<(T Data, string LogId)> HttpPostAsync<T>(string host, string apiName, IDictionary<string, string> dicParameters, Dictionary<string, string> headers = null, int timeout = 100, HttpContentType contentType = HttpContentType.Json, bool isMultilevelNestingJson = false, Dictionary<string, string> authorization = null)
        {
            var client = clientFactory.CreateClient("base");
            {
                #region Http基础设置

                //设置接口超时时间
                if (timeout > 0)
                {
                    client.Timeout = new TimeSpan(0, 0, timeout);
                }
                //身份认证
                if (authorization != null)
                {
                    foreach (var item in authorization)
                    {
                        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(item.Key, item.Value);
                    }
                }

                var _contentType = (contentType == HttpContentType.Json ? "application/json" : "application/x-www-form-urlencoded");
                HttpContent content;
                if (contentType == HttpContentType.Json)
                {
                    if (isMultilevelNestingJson)
                        content = new StringContent(dicParameters["json"]);
                    else
                        content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(dicParameters));
                }
                else
                {
                    content = new FormUrlEncodedContent(dicParameters);
                }
                content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(_contentType);
                //设置HTTP请求头
                if (headers != null)
                {
                    foreach (KeyValuePair<string, string> header in headers)
                    {
                        content.Headers.Add(header.Key, header.Value);
                    }
                }

                #endregion

                #region 新增请求日志

                var log_request_param = new AddRequestLogParam
                {
                    APIName = apiName.ToString().ToLower(),
                    ClientHost = PoJun.Util.Helpers.Web.Ip,
                    RequestTime = DateTime.Now,
                    ServerHost = host,
                    SystemID = SysUtil.GetSystemId(),
                    TraceID = PoJun.Util.Helpers.Id.GetGuidBy32(),
                    Level = 2,
                    ParentTraceID = SysUtil.GetTraceId(),
                    RequestBody = Newtonsoft.Json.JsonConvert.SerializeObject(dicParameters)
                };
                if (SysUtil.GetTraceId() != null)
                {
                    log_request_param.Level = 2;
                    log_request_param.ParentTraceID = SysUtil.GetTraceId();
                }
                else
                {
                    log_request_param.Level = 1;
                }
                try
                {
                    await apiLogService.AddRequestLogAsync(log_request_param);
                }
                catch (System.Exception)
                {
                    //记录文本日志
                    logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_request_param)},");
                }

                #endregion

                #region 发起Http请求

                var url = $"{host}{apiName}";
                var strResult = string.Empty;
                HttpResponseMessage events = null;
                System.Exception exs = null;

                try
                {
                    //异步发送请求
                    events = await client.PostAsync(url, content);
                    if (events != null && events.IsSuccessStatusCode)
                        //异步获取请求的结果
                        strResult = await events.Content.ReadAsStringAsync();
                }
                catch (System.Exception ex)
                {
                    exs = ex;
                }
                finally
                {
                    #region 新增响应日志

                    var log_response_param = new AddResponseLogParam
                    {
                        IsError = false,
                        ResponseBody = strResult,
                        ResponseTime = DateTime.Now,
                        ParentTraceID = log_request_param.TraceID
                    };
                    log_response_param.TimeCost = Convert.ToInt32((log_response_param.ResponseTime - log_request_param.RequestTime).TotalMilliseconds);
                    if (events != null)
                        log_response_param.ErrorBody = $"StatusCode：{events.StatusCode} | events: {Newtonsoft.Json.JsonConvert.SerializeObject(events)}";
                    else
                        log_response_param.ErrorBody = $"Message：{exs.Message} | StackTrace: {exs.StackTrace} | Source: {exs.Source} | InnerException： {exs.InnerException?.ToString()}";
                    try
                    {
                        await apiLogService.AddResponseLogAsync(log_response_param);
                    }
                    catch (System.Exception)
                    {
                        //记录文本日志
                        logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_response_param)},");
                    }

                    #endregion
                }

                #endregion

                #region 返回结果

                if (string.IsNullOrEmpty(strResult))
                    return (default(T), log_request_param.TraceID);
                return (Newtonsoft.Json.JsonConvert.DeserializeObject<T>(strResult), log_request_param.TraceID);

                #endregion
            }
        }


        /// <summary>
        /// Post请求[异步]
        /// </summary>
        /// <param name="host">域名</param>
        /// <param name="apiName">接口名称(接口地址)</param>
        /// <param name="dicParameters">接口参数</param>
        /// <param name="headers">请求头</param>
        /// <param name="timeout">请求响应超时时间，单位/s(默认100秒)</param>
        /// <param name="contentType">请求类型</param>
        /// <param name="isMultilevelNestingJson">是否为多层嵌套json</param>
        /// <param name="authorization">身份认证</param>
        /// <returns></returns>
        public async Task<(string Data, string LogId)> HttpPostAsync(string host, string apiName, IDictionary<string, string> dicParameters, Dictionary<string, string> headers = null, int timeout = 100, HttpContentType contentType = HttpContentType.Json, bool isMultilevelNestingJson = false, Dictionary<string, string> authorization = null)
        {
            var client = clientFactory.CreateClient("base");
            {
                #region Http基础设置

                //设置接口超时时间
                if (timeout > 0)
                {
                    client.Timeout = new TimeSpan(0, 0, timeout);
                }
                //身份认证
                if (authorization != null)
                {
                    foreach (var item in authorization)
                    {
                        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(item.Key, item.Value);
                    }
                }

                var _contentType = (contentType == HttpContentType.Json ? "application/json" : "application/x-www-form-urlencoded");
                HttpContent content;
                if (contentType == HttpContentType.Json)
                {
                    if (isMultilevelNestingJson)
                        content = new StringContent(dicParameters["json"]);
                    else
                        content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(dicParameters));
                }
                else
                {
                    content = new FormUrlEncodedContent(dicParameters);
                }
                content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(_contentType);
                //设置HTTP请求头
                if (headers != null)
                {
                    foreach (KeyValuePair<string, string> header in headers)
                    {
                        content.Headers.Add(header.Key, header.Value);
                    }
                }

                #endregion

                #region 新增请求日志

                var log_request_param = new AddRequestLogParam
                {
                    APIName = apiName.ToString().ToLower(),
                    ClientHost = PoJun.Util.Helpers.Web.Ip,
                    RequestTime = DateTime.Now,
                    ServerHost = host,
                    SystemID = SysUtil.GetSystemId(),
                    TraceID = PoJun.Util.Helpers.Id.GetGuidBy32(),
                    Level = 2,
                    ParentTraceID = SysUtil.GetTraceId(),
                    RequestBody = Newtonsoft.Json.JsonConvert.SerializeObject(dicParameters)
                };
                if (SysUtil.GetTraceId() != null)
                {
                    log_request_param.Level = 2;
                    log_request_param.ParentTraceID = SysUtil.GetTraceId();
                }
                else
                {
                    log_request_param.Level = 1;
                }
                try
                {
                    await apiLogService.AddRequestLogAsync(log_request_param);
                }
                catch (System.Exception)
                {
                    //记录文本日志
                    logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_request_param)},");
                }

                #endregion

                #region 发起Http请求

                var url = $"{host}{apiName}";
                var strResult = string.Empty;
                HttpResponseMessage events = null;
                System.Exception exs = null;

                try
                {
                    //异步发送请求
                    events = await client.PostAsync(url, content);
                    if (events != null && events.IsSuccessStatusCode)
                        //异步获取请求的结果
                        strResult = await events.Content.ReadAsStringAsync();
                }
                catch (System.Exception ex)
                {
                    exs = ex;
                }
                finally
                {
                    #region 新增响应日志

                    var log_response_param = new AddResponseLogParam
                    {
                        IsError = false,
                        ResponseBody = strResult,
                        ResponseTime = DateTime.Now,
                        ParentTraceID = log_request_param.TraceID
                    };
                    log_response_param.TimeCost = Convert.ToInt32((log_response_param.ResponseTime - log_request_param.RequestTime).TotalMilliseconds);
                    if (events != null)
                        log_response_param.ErrorBody = $"StatusCode：{events.StatusCode} | events: {Newtonsoft.Json.JsonConvert.SerializeObject(events)}";
                    else
                        log_response_param.ErrorBody = $"Message：{exs.Message} | StackTrace: {exs.StackTrace} | Source: {exs.Source} | InnerException： {exs.InnerException?.ToString()}";
                    try
                    {
                        await apiLogService.AddResponseLogAsync(log_response_param);
                    }
                    catch (System.Exception)
                    {
                        //记录文本日志
                        logger.LogCritical($"{Newtonsoft.Json.JsonConvert.SerializeObject(log_response_param)},");
                    }

                    #endregion
                }

                #endregion

                #region 返回结果

                return (strResult, log_request_param.TraceID);

                #endregion
            }
        }

        #endregion
    }
}
