using CsharpHttpHelper;
using CsharpHttpHelper.Enum;
using DeviceRepair.Models;
using DeviceRepair.Utils;
using DeviceRepair.Utils.Security;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace DeviceRepairAndOptimization.Biz
{
    public class ApiHelper
    {
        HttpHelper http = null;
        public static readonly string ServiceUrl = $"http://{DeviceRepair.Utils.Config.Configurations.Properties.ServiceIP}/{DeviceRepair.Utils.Config.Configurations.Properties.ServiceName}/";

        private static ApiHelper manager;

        public static ApiHelper Instance
        {
            get
            {
                if (manager == null)
                    manager = new ApiHelper();
                return manager;
            }
        }

        /// <summary>
        /// 方法参数初始化
        /// </summary>
        /// <param name="item"></param>
        public void Init(ref HttpItem item)
        {
            if (http == null)
                http = new HttpHelper();

            if (item == null)
                throw new Exception("调用API失败,参数不能为null!");

            if (string.IsNullOrEmpty(ServiceUrl))
                throw new Exception("调用API失败,参数ServiceUrl不能为null!");

            item.Header.Add("auth", GlobalInfo.token);
            item.Header.Add("Operator", GlobalInfo.CurrentUser == null ? "" : GlobalInfo.CurrentUser?.AutoID + "");
            item.Header.Add("OperatorCode", GlobalInfo.CurrentUser == null ? "" : EncryptionHelper.UrlEncry(GlobalInfo.CurrentUser?.LoginCode));
            item.Header.Add("OperatorName", GlobalInfo.CurrentUser == null ? "" : EncryptionHelper.UrlEncry(GlobalInfo.CurrentUser?.RealName));
            item.Header.Add("ClientMac", ComputerHelper.GetMacAddress);
            item.Header.Add("IPAddress", ComputerHelper.GetIPAddress);
            item.Header.Add("ClientName", ComputerHelper.GetComputerName);

            item.Timeout = 30000;
            item.PostEncoding = Encoding.UTF8;
            item.URL = JoinUrl(item.URL);
        }

        /// <summary>
        /// URL 拼接
        /// </summary>
        /// <param name="relativePath"></param>
        /// <returns></returns>
        private string JoinUrl(string relativePath)
        {
            relativePath = relativePath.TrimStart('/');

            // 使用 UriKind.Absolute 表示 baseUrl 是绝对路径
            var baseUri = new Uri(ServiceUrl, UriKind.Absolute);

            var relativeUri = new Uri(baseUri, relativePath);
            return relativeUri.ToString();
        }

        public APIResponseData SendMessage(HttpItem item)
        {
            try
            {
                Init(ref item);
                //请求的返回值对象
                HttpResult result = http.GetHtml(item);

                if (result.StatusCode != HttpStatusCode.OK)
                    throw new Exception(result.Html);

                //获取返回值
                APIResponseData apiResponseData = JsonConvert.DeserializeObject<APIResponseData>(result.Html);
                return apiResponseData;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        public void SendMessageAsync(HttpItem item, ResultHandler resultHandler)
        {
            try
            {
                Init(ref item);
                //开始异步调用
                http.BeginInvokeGetHtml(item, resultHandler);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        public string DownLoadFile(HttpItem item)
        {
            try
            {
                Init(ref item);
                item.ResultType = ResultType.Byte;
                //请求的返回值对象
                HttpResult result = http.GetHtml(item);

                WebHeaderCollection header = result.Header;
                if (header != null)
                {
                    string fileName = header["FileName"];
                    if (!string.IsNullOrWhiteSpace(fileName))
                    {
                        string CurrentDirectory = AppDomain.CurrentDomain.BaseDirectory;
                        if (!Directory.Exists(Path.Combine(CurrentDirectory, "Cache")))
                            Directory.CreateDirectory(Path.Combine(CurrentDirectory, "Cache"));

                        File.WriteAllBytes(Path.Combine(CurrentDirectory, "Cache", fileName), result.ResultByte);
                        return Path.Combine(CurrentDirectory, "Cache", fileName);
                    }
                }
                return string.Empty;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 获取服务器时间
        /// </summary>
        /// <returns></returns>
        public string GetServiceTime()
        {
            try
            {
                HttpItem item = new HttpItem
                {
                    URL = ServiceRouteConstValue.GetCurrentTime,
                    Method = "Get",
                    ContentType = "application/text; charset=utf-8",
                };
                Init(ref item);

                //请求的返回值对象
                HttpResult result = http.GetHtml(item);
                //获取返回值
                string CurrentDateTime = result.Html.Trim('"');
                return CurrentDateTime ?? "";
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        public APIResponseData PostWebRequest(string postUrl, string paramData, string token)
        {
            string ret = string.Empty;
            try
            {
                byte[] byteArray = Encoding.UTF8.GetBytes(paramData); //转化 /
                HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(JoinUrl(postUrl));
                webReq.Method = "POST";
                webReq.ContentType = "application/json; charset=utf-8";
                webReq.ContentLength = byteArray.Length;
                webReq.Credentials = CredentialCache.DefaultCredentials;

                if (!string.IsNullOrEmpty(token))
                    webReq.Headers.Add("auth", token);
                Stream newStream = webReq.GetRequestStream();
                newStream.Write(byteArray, 0, byteArray.Length);//写入参数
                newStream.Close();
                HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
                StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                ret = sr.ReadToEnd();
                sr.Close();
                response.Close();
                newStream.Close();
                return JsonConvert.DeserializeObject<APIResponseData>(ret);
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
        /// 文件上传
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public async Task<APIResponseData> UploadFileAsync(string ServerUrl, FileStream fileStream, string fileName)
        {
            try
            {
                ServerUrl = JoinUrl(ServerUrl);

                using (HttpClient _httpClient = new HttpClient())
                //using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                using (var multipartContent = new MultipartFormDataContent())
                {
                    _httpClient.DefaultRequestHeaders.Add("auth", GlobalInfo.token);
                    var fileContent = new StreamContent(fileStream);
                    fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("multipart/form-data");
                    fileContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
                    {
                        FileName = fileName,
                        Size = fileStream.Length
                    };

                    multipartContent.Add(fileContent, "file", fileName);

                    HttpResponseMessage response = await _httpClient.PostAsync(ServerUrl, multipartContent);
                    if (response.IsSuccessStatusCode)
                    {
                        string content = await response.Content.ReadAsStringAsync();
                        return JsonConvert.DeserializeObject<APIResponseData>(content);
                    }

                    return new APIResponseData { Code = -1 };
                }
            }
            catch (Exception e)
            {
                return new APIResponseData { Code = -1, Message = e.Message };
            }
        }

    }
}
