using Newtonsoft.Json;
using System.Net.Http.Headers;
using System.Net;
namespace LY.App.Common.HttpUtil
{
    public static class RequestUtil
    {
        /// 
        /// 是否已经初始化加密协议
        /// 
        private static bool _securitinit = false;
        /// 
        /// 初始化加密协议
        /// 
        public static void InitialSecurity()
        {
            if (_securitinit) return;
            try
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
                    | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;
            }
            catch (Exception)
            {
                try
                {
                    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
                        | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
                }
                catch (Exception)
                {
                    try
                    {
                        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11;
                    }
                    catch (Exception)
                    {
                        try
                        {
                            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
                        }
                        catch (Exception) { }
                    }
                }
            }
            ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true;
            _securitinit = true;
        }
        /// 
        /// 获取HTTP连接
        /// 
        /// 是否ssl连接
        /// 
        public static HttpClient GetClient(bool haveSSL)
        {
            if (haveSSL)
            {
                InitialSecurity();
                var handle = new HttpClientHandler();
                handle.ServerCertificateCustomValidationCallback
                    = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
                return new HttpClient(handle);
            }
            else return new HttpClient();
        }
        /// 
        /// 异步请求GET
        /// 
        /// 网址
        /// 头部信息
        /// 验证信息
        /// 过期时间
        /// 
        public static async Task GetAsync(string url,
        Dictionary headers = null,
        AuthenticationHeaderValue auth = null, int timeout = 5000)
        {
            using (var client = GetClient(url.StartsWith("https")))
            {
                client.Timeout = TimeSpan.FromMilliseconds(timeout);
                if (headers != null && headers.Any())
                {
                    foreach (var item in headers)
                    {
                        client.DefaultRequestHeaders.Add(item.Key, item.Value);
                    }
                }
                if (auth != null)
                    client.DefaultRequestHeaders.Authorization = auth;
                var result = await client.GetAsync(url);
                if (result.IsSuccessStatusCode)
                    return await result.Content.ReadAsStringAsync();
            }
            return null;
        }
        /// 
        /// 异步请求GET
        /// 
        /// 网址
        /// 头部信息
        /// 验证信息
        /// 过期时间
        /// 
        public static async Task GetStreamAsync(string url,
            Dictionary headers = null,
            AuthenticationHeaderValue auth = null, int timeout = 5000)
        {
            using (var client = GetClient(url.StartsWith("https")))
            {
                client.Timeout = TimeSpan.FromMilliseconds(timeout);
                if (headers != null && headers.Any())
                {
                    foreach (var item in headers)
                    {
                        client.DefaultRequestHeaders.Add(item.Key, item.Value);
                    }
                }
                if (auth != null)
                    client.DefaultRequestHeaders.Authorization = auth;
                var result = await client.GetAsync(url);
                if (result.IsSuccessStatusCode)
                    return await result.Content.ReadAsStreamAsync();
            }
            return null;
        }
        /// 
        /// 删除
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static async Task DeleteAsync(string url,
            Dictionary headers = null,
            AuthenticationHeaderValue auth = null, int timeout = 5000)
        {
            using (var client = GetClient(url.StartsWith("https")))
            {
                client.Timeout = TimeSpan.FromMilliseconds(timeout);
                if (headers != null && headers.Any())
                {
                    foreach (var item in headers)
                    {
                        client.DefaultRequestHeaders.Add(item.Key, item.Value);
                    }
                }
                if (auth != null)
                    client.DefaultRequestHeaders.Authorization = auth;
                var result = await client.DeleteAsync(url);
                if (result.IsSuccessStatusCode)
                    return await result.Content.ReadAsStringAsync();
            }
            return null;
        }
        /// 
        /// 异步请求并解析
        /// 
        /// 
        /// 网址
        /// 头部信息
        /// 验证信息
        /// 过期时间
        /// 
        public static async Task GetAsync(string url,
            Dictionary headers = null,
            AuthenticationHeaderValue auth = null,
            int timeout = 5000)
        {
            var result = await GetAsync(url, headers, auth, timeout);
            if (result != null)
                return JsonConvert.DeserializeObject(result);
            return default;
        }
        /// 
        /// 返回btye[]
        /// 
        /// 
        /// 
        public static async Task GetAsync(string url)
        {
            using (var client = GetClient(url.StartsWith("https")))
            {
                client.Timeout = TimeSpan.FromMilliseconds(2000);
                var result = await client.GetAsync(url);
                if (result.IsSuccessStatusCode)
                    return await result.Content.ReadAsByteArrayAsync();
            }
            return null;
        }
        public static AuthenticationHeaderValue GetTokenHeader(string token)
        {
            return new AuthenticationHeaderValue("Bearer", token);
        }
        /// 
        /// 异步请求POST
        /// 
        /// 网址
        /// 信息
        /// 头部信息
        /// 验证信息
        /// 过期时间
        /// 
        public static async Task PostAsync(string url,
            string dataJson = null,
            Dictionary headers = null,
            AuthenticationHeaderValue auth = null, int timeout = 5000)
        {
            using (var client = GetClient(url.StartsWith("https")))
            {
                client.Timeout = TimeSpan.FromMilliseconds(timeout);
                if (headers != null && headers.Any())
                {
                    foreach (var item in headers)
                    {
                        client.DefaultRequestHeaders.Add(item.Key, item.Value);
                    }
                }
                if (auth != null)
                    client.DefaultRequestHeaders.Authorization = auth;
                StringContent content = null;
                if (dataJson != null)
                {
                    content = new StringContent(dataJson);
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                }
                var result = await client.PostAsync(url, content);
                if (result.IsSuccessStatusCode)
                    return await result.Content.ReadAsStringAsync();
            }
            return null;
        }
        /// 
        /// 异步请求POST
        /// 
        /// 网址
        /// 消息
        /// 头部信息
        /// 验证信息
        /// 过期时间
        /// 
        public static async Task PostAsync(string url,
            Dictionary data,
            Dictionary headers = null,
            AuthenticationHeaderValue auth = null, int timeout = 5000)
        {
            return await PostAsync(url, JsonConvert.SerializeObject(data), headers, auth, timeout);
        }
        /// 
        /// 异步请求POST
        /// 
        /// 
        /// 网址
        /// 信息
        /// 头部信息
        /// 验证信息
        /// 过期时间
        /// 
        public static async Task PostAsync(string url,
            string dataJson = null,
            Dictionary headers = null,
            AuthenticationHeaderValue auth = null, int timeout = 5000)
        {
            var result = await PostAsync(url, dataJson, headers, auth, timeout);
            return JsonConvert.DeserializeObject(result);
        }
        /// 
        /// 
        /// 
        /// 
        /// 网址
        /// 消息
        /// 头部信息
        /// 验证信息
        /// 过期时间
        /// 
        public static async Task PostAsync(string url,
            Dictionary data = null,
            Dictionary headers = null,
            AuthenticationHeaderValue auth = null, int timeout = 5000)
        {
            return await PostAsync(url, JsonConvert.SerializeObject(data), headers, auth, timeout);
        }
        /// 
        /// 异步推送数据流
        /// 
        /// 网址
        /// 数据流
        /// 头部信息
        /// 验证信息
        /// 过期时间
        /// 
        public static async Task PutStreamAsync(
            string url, Stream stream,
            Dictionary headers = null,
            AuthenticationHeaderValue auth = null, int timeout = 10000)
        {
            using (var client = GetClient(url.StartsWith("https")))
            {
                client.Timeout = TimeSpan.FromMilliseconds(timeout);
                if (headers != null && headers.Any())
                {
                    foreach (var item in headers)
                    {
                        client.DefaultRequestHeaders.Add(item.Key, item.Value);
                    }
                }
                if (auth != null)
                    client.DefaultRequestHeaders.Authorization = auth;
                StreamContent content = null;
                if (stream != null)
                {
                    content = new StreamContent(stream);
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                }
                var result = await client.PutAsync(url, content);
                if (result.IsSuccessStatusCode)
                    return await result.Content.ReadAsStringAsync();
            }
            return null;
        }
        /// 
        /// 异步推送数据流
        /// 
        /// 网址
        /// 数据流
        /// 头部信息
        /// 验证信息
        /// 过期时间
        /// 
        public static async Task PutStreamAsync(
            string url, Stream stream,
            Dictionary headers = null,
            AuthenticationHeaderValue auth = null, int timeout = 10000)
        {
            var result = await PutStreamAsync(url, stream, headers, auth, timeout);
            return JsonConvert.DeserializeObject(result);
        }
        /// 
        /// PUT请求
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static async Task PutAsync(string url,
               string dataJson = null,
            Dictionary headers = null,
            AuthenticationHeaderValue auth = null, int timeout = 5000)
        {
            using (var client = GetClient(url.StartsWith("https")))
            {
                client.Timeout = TimeSpan.FromMilliseconds(timeout);
                if (headers != null && headers.Any())
                {
                    foreach (var item in headers)
                    {
                        client.DefaultRequestHeaders.Add(item.Key, item.Value);
                    }
                }
                if (auth != null)
                    client.DefaultRequestHeaders.Authorization = auth;
                StringContent content = null;
                if (dataJson != null)
                {
                    content = new StringContent(dataJson);
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                }
                var result = await client.PutAsync(url, content);
                if (result.IsSuccessStatusCode)
                    return await result.Content.ReadAsStringAsync();
            }
            return null;
        }
    }
}