using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace Server.Core
{
    /// <summary>
    /// Http请求帮助类
    /// </summary>
    public class HttpHelper
    {
        public static Task<string> HttpPostFormAsync(string url, Dictionary<string, string> parms,
            Dictionary<string, string> heads = null)
        {
            return Task.Run(() => HttpPostFrom(url, parms, heads));
        }

        /// <summary>
        /// From post 请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="parms">请求参数</param>
        /// <returns></returns>
        public static string HttpPostFrom(string url, Dictionary<string, string> parms, Dictionary<string, string> heads = null)
        {
            string htmlAll = "";
            StringBuilder builder = new StringBuilder();
            if (parms != null && parms.Count > 0)
            {
                int i = 0;
                foreach (var item in parms)
                {
                    if (i > 0)
                        builder.Append("&");
                    builder.AppendFormat("{0}={1}", item.Key, item.Value);
                    i++;
                }
            }
            string SendMessageAddress = url;//请求链接
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(SendMessageAddress);
            request.Method = "POST";
            request.AllowAutoRedirect = true;
            request.Timeout = 8 * 1000;
            request.ContentType = "application/x-www-form-urlencoded";
            if (heads != null)
            {
                foreach (var item in heads)
                {
                    request.Headers.Add(item.Key, item.Value);
                }
            }
            //string PostData = "a=1&b=2";//请求参数格式
            string PostData = builder.ToString();//请求参数
            byte[] byteArray = Encoding.Default.GetBytes(PostData);
            request.ContentLength = byteArray.Length;
            using (Stream newStream = request.GetRequestStream())
            {
                newStream.Write(byteArray, 0, byteArray.Length);//写入参数
            }

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream rspStream = response.GetResponseStream();
            using (StreamReader reader = new StreamReader(rspStream, Encoding.UTF8))
            {
                htmlAll = reader.ReadToEnd();
                rspStream.Close();
            }
            response.Close();
            return htmlAll;
        }

        public static Task<string> PostAsync(string url, Dictionary<string, string> head = null)
        {
            return Task.Run(() => Post(url, head));
        }

        public static string Post(string url, Dictionary<string, string> head = null)
        {
            try
            {
                string result = "";
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
                if (head != null)
                {
                    foreach (var item in head)
                    {
                        req.Headers[item.Key] = item.Value;
                    }
                }
                req.Method = "Post";
                req.ContentType = "application/json;charset=utf-8";
                req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36";
                req.Timeout = 5000;
                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                Stream stream = resp.GetResponseStream();
                //获取内容  
                using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                {
                    result = reader.ReadToEnd();
                }
                return result;
            }
            catch (Exception e)
            {
                Console.WriteLine($"err msg:{e.Message},code:{e.StackTrace}");
                return null;
            }
        }

        public static Task<string> PostAsync(string url, byte[] data, Dictionary<string, string> head = null)
        {
            return Task.Run(() => Post(url, data, head));
        }

        public static string Post(string url, byte[] data,Dictionary<string, string> head = null)
        {
            string result = "";
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            if (head != null)
            {
                foreach (var item in head)
                {
                    req.Headers[item.Key] = item.Value;
                }
            }
            req.Method = "Post";
            req.ContentType = "application/json;charset=utf-8";
            req.Timeout = 5000;
            req.KeepAlive = false;
            req.ProtocolVersion = HttpVersion.Version10;
            req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36";
            req.ContentLength = data.Length;
            using (Stream reqStream = req.GetRequestStream())
            {
                reqStream.Write(data, 0, data.Length);
                reqStream.Close();
            }
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            Stream stream = resp.GetResponseStream();
            //获取响应内容  
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            }
            return result;
        }

        public static async Task<string> PostAsync(string url, string pam, Dictionary<string, string> head = null)
        {
            string result = "";

            using (HttpClient client = new HttpClient())
            {
                if (head != null)
                {
                    foreach (var item in head)
                    {
                        client.DefaultRequestHeaders.TryAddWithoutValidation(item.Key, item.Value);
                    }
                }

                // 设置请求头
                client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");
                var content = new StringContent(pam, Encoding.UTF8, "application/json");

                // 发送POST请求
                HttpResponseMessage response = await client.PostAsync(url, content);

                // 确保响应成功
                response.EnsureSuccessStatusCode();

                // 读取响应内容
                result = await response.Content.ReadAsStringAsync();
            }

            return result;
        }

        public static string Post(string url, string pam, Dictionary<string, string> head = null)
        {
            string result = "";
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            if (head != null)
            {
                foreach (var item in head)
                {
                    req.Headers[item.Key] = item.Value;
                }
            }
            req.Method = "Post";
            req.ContentType = "application/json;charset=utf-8";
            req.Timeout = 5000;
            req.KeepAlive = false;
            req.ProtocolVersion = HttpVersion.Version10;
            req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36";
            byte[] data = Encoding.UTF8.GetBytes(pam);
            req.ContentLength = data.Length;
            using (Stream reqStream = req.GetRequestStream())
            {
                reqStream.Write(data, 0, data.Length);
                reqStream.Close();
            }
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            Stream stream = resp.GetResponseStream();
            //获取响应内容  
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            }
            return result;
        }

        public static Task<string> PostFileAsync(string url, string filePath, Dictionary<string, string> head = null)
        {
            return Task.Run(() => PostFile(url, filePath, head));
        }

        public static string PostFile(string url, string filePath, Dictionary<string, string> head = null)
        {
            string result = "";
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            if (head != null)
            {
                foreach (var item in head)
                {
                    req.Headers[item.Key] = item.Value;
                }
            }
            byte[] fileBytes = File.ReadAllBytes(filePath);
            string boundary = "------------------------" + DateTime.Now.Ticks.ToString("x");
            
            req.Method = "Post";
            req.ContentType = "multipart/form-data; boundary=" + boundary;
            req.Timeout = 30000;
            req.ProtocolVersion = HttpVersion.Version10;
            req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36";
            // 构建请求体
            using (Stream requestStream = req.GetRequestStream())
            {
                // 开始边界
                string header = $"--{boundary}\r\nContent-Disposition: form-data; name=\"media\"; filename=\"{Path.GetFileName(filePath)}\"\r\nContent-Type: application/octet-stream\r\n\r\n";
                byte[] headerBytes = Encoding.UTF8.GetBytes(header);
                requestStream.Write(headerBytes, 0, headerBytes.Length);
            
                // 文件内容
                requestStream.Write(fileBytes, 0, fileBytes.Length);
            
                // 结束边界
                string footer = "\r\n--" + boundary + "--\r\n";
                byte[] footerBytes = Encoding.UTF8.GetBytes(footer);
                requestStream.Write(footerBytes, 0, footerBytes.Length);
            }

            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            Stream stream = resp.GetResponseStream();
            //获取响应内容  
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            }
            return result;
        }
        
        public static Task<string> GetAsync(string url, Dictionary<string, string> head = null)
        {
            return Task.Run(() => Get(url, head));
        }

        public static string Get(string url, Dictionary<string, string> head = null)
        {
            string result = "";
            try
            {
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
                if (head != null)
                {
                    foreach (var item in head)
                    {
                        req.Headers[item.Key] = item.Value;
                    }
                }
                req.Method = "GET";
                req.Timeout = 5000;
                req.ContentType = "application/json;charset=utf-8";
                req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36";
                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                Stream stream = resp.GetResponseStream();
                try
                {
                    //获取内容  
                    using (StreamReader reader = new StreamReader(stream))
                    {
                        result = reader.ReadToEnd();
                    }
                }
                finally
                {
                    stream.Close();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"err msg:{e.Message},code:{e.StackTrace}");
            }
            return result;
        }

        public static Task<string> GetAsync(string url, Dictionary<string, string> parms, Dictionary<string, string> head = null)
        {
            return Task.Run(() => Get(url, parms, head));
        }
        
        public static string Get(string url, Dictionary<string, string> parms, Dictionary<string, string> head = null)
        {
            string result = "";
            StringBuilder builder = new StringBuilder();
            builder.Append(url);
            if (parms.Count > 0)
            {
                builder.Append("?");
                int i = 0;
                foreach (var item in parms)
                {
                    if (i > 0)
                        builder.Append("&");
                    builder.AppendFormat("{0}={1}", item.Key, item.Value);
                    i++;
                }
            }
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(builder.ToString());
            if (head != null)
            {
                foreach (var item in head)
                {
                    req.Headers[item.Key] = item.Value;
                }
            }
            req.Method = "GET";
            req.Timeout = 5000;
            req.ContentType = "application/json;charset=utf-8";
            req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36";
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            Stream stream = resp.GetResponseStream();
            try
            {
                //获取内容
                using (StreamReader reader = new StreamReader(stream))
                {
                    result = reader.ReadToEnd();
                }
            }
            finally
            {
                stream.Close();
            }

            return result;
        }

        /// <summary>
        /// Post请求并返回二进制数据和Content-Type
        /// </summary>
        public static async Task<(byte[] data, string contentType)> PostGetBytesAsync(string url, string jsonBody, Dictionary<string, string> head = null)
        {
            using (HttpClient client = new HttpClient())
            {
                if (head != null)
                {
                    foreach (var item in head)
                    {
                        client.DefaultRequestHeaders.TryAddWithoutValidation(item.Key, item.Value);
                    }
                }

                client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");
                var content = new StringContent(jsonBody, Encoding.UTF8, "application/json");

                HttpResponseMessage response = await client.PostAsync(url, content);
                response.EnsureSuccessStatusCode();

                byte[] data = await response.Content.ReadAsByteArrayAsync();
                string contentType = response.Content.Headers.ContentType?.ToString();

                return (data, contentType);
            }
        }
    }
}
