using Newtonsoft.Json.Linq;
using PTMedicalInsurance.Common;
using PTMedicalInsurance.Variables;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PTMedicalInsurance.Helper
{
    class InvokeRestCenter : IInvokeCenter
    {
        private static string GetRandomString(int length)
        {
            const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            //const string chars = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
            var random = new Random();
            return new string(Enumerable.Repeat(chars, length)
              .Select(s => s[random.Next(s.Length)]).ToArray());
        }

        private static long GetCurrentUnixSeconds()
        {
            DateTimeOffset utcNow = DateTimeOffset.UtcNow.AddHours(8);
            return (long)(utcNow.ToUniversalTime().DateTime.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc))).TotalSeconds;
        }

        private static string GetSHA256Str(string input)
        {
            using (SHA256 sha256Hash = SHA256.Create())
            {
                byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
                StringBuilder builder = new StringBuilder();
                foreach (byte b in bytes)
                {
                    builder.Append(b.ToString("x2"));
                }
                return builder.ToString();
            }
        }

        public int Business(string inputData, ref string outputData, ref string pErrMsg)
        {
            outputData = "";
            pErrMsg = "";
            
            JObject joRtn = new JObject();
            try
            {
                if (Global.curEvt.funNo.Contains("CFYLJG"))
                {
                    //Global.curEvt.URL = "http://igb.hsa.gdgov.cn/ebus/gdyb_inf/poc/hsa/hgs/" + Global.curEvt.funNo;

                    //电子处方测试
                    Global.inf.apiSecretKey = "4poYlzt2jteX1pT3tijh7BqyWH4Lp0zN";
                    Global.inf.passid = "sztest_hosp";
                    Global.curEvt.URL = "http://hosp-sz.gd.hsip.gov.cn/ebus/sztest_hosp/poc/hsa/hgs/" + Global.curEvt.funNo;
                }
                //创建一个HTTP请求  
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Global.curEvt.URL);
                //Post请求方式  
                request.Method = "POST";
                string nonce = Guid.NewGuid().ToString();         //非重复的随机字符串(十分钟内不能重复)
                string timestamp = TimeStamp.get10().ToString();  //当前时间戳(秒)

                //测试
                //string secretKey = "RhaDw4H0RUbWYyTxmRKM1eSeN0qyGLds";
                //string passid = "test_hosp";

                //正式
                //string secretKey = "4G9PvAy1xEkvgZJGZ0cNOacQZZYe2Bkg";
                //string passid = "dg_sc_yjyy";

                string secretKey = Global.inf.apiSecretKey;
                string passid = Global.inf.passid;

                //内容类型
                request.ContentType = "application/json";

                //签名
                string sTemp = timestamp + secretKey + nonce + timestamp;
                //Sha256 加密生成的签名 x-tif-signature = sha256(x-tif-timestamp + secretKey+ x-tif-nonce + xtif-timestamp)
                string signature = Encrypt.SHA256EncryptStr(sTemp);


                nonce = GetRandomString(32); // 随机数
                //timestamp = GetCurrentUnixSeconds().ToString();
                signature = GetSHA256Str($"{timestamp}{secretKey}{nonce}{timestamp}"); // 签名

                //Global.writeLog($"nonce:{nonce}\ntimestamp:{timestamp}\nsecretKey:{secretKey}\npassid:{passid}\nsignature:{signature}");

                //增加头部信息
                request.Headers.Add("x-tif-paasid", passid);
                request.Headers.Add("x-tif-timestamp", timestamp);
                request.Headers.Add("x-tif-signature", signature);
                request.Headers.Add("x-tif-nonce", nonce);

                //设置参数,并进行URL编码 
                string paraUrlCoded = inputData;//System.Web.HttpUtility.UrlEncode(jsonParas);   
                byte[] payload;
                //将Json字符串转化为字节  
                payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);
                //设置请求的ContentLength   
                request.ContentLength = payload.Length;
                //发送请求,获得请求流 
                Stream writer;
                writer = request.GetRequestStream();//获取用于写入请求数据的Stream对象
                                                    //将请求参数写入流
                writer.Write(payload, 0, payload.Length);
                writer.Close();//关闭请求流
                HttpWebResponse response = null;
                try
                {
                    //获得响应流
                    response = (HttpWebResponse)request.GetResponse();           
                }
                catch (WebException ex)
                {
                    HttpWebResponse res = (HttpWebResponse)ex.Response;
                    Stream myResponseStream = res.GetResponseStream();
                    StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
                    string retString = myStreamReader.ReadToEnd();
                    outputData = JsonHelper.setExceptionJson(-99, "异常返回", retString).ToString();
                    return -1;
                }               

                outputData = getResponseData(response);
                joRtn = JObject.Parse(outputData);//返回Json数据                                           

                return 0;

            }
            catch (Exception ex)
            {
                joRtn.Add("infcode", -1);
                joRtn.Add("err_msg", "调用中心服务异常invokeCenterService(1):" + ex.Message);
                outputData = JsonHelper.toJsonString(joRtn);

                return -1;
            }
        }       

        public int BusinessExt(string inputData, ref string outputData, ref string pErrMsg)
        {
            return this.Business(inputData, ref outputData, ref pErrMsg);
        }

        public int DownloadFile(string inputData, ref string outputData)
        {
            outputData = "";
            string error = string.Empty; int errorCode = 0;
            try
            {
                JObject jsonInParam = JObject.Parse(inputData);
                // 去除外wrapper层便于通用
                Utils.removeWrapper(jsonInParam);

                string fileName = (string)jsonInParam["input"]["fsDownloadIn"]["filename"];
                string filePath = Global.curEvt.path + "\\Download\\" + fileName;

                //如果不存在目录,则创建目录
                if (!Directory.Exists(Global.curEvt.path + "\\Download"))
                {
                    //创建文件夹
                    DirectoryInfo dirInfo = Directory.CreateDirectory(Global.curEvt.path + "\\Download");
                }
                if (File.Exists(filePath))
                {
                    File.Delete(filePath);
                }                

                FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
                //创建一个HTTP请求  
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Global.curEvt.URL);
                //Post请求方式  
                request.Method = "POST";
                string nonce = Guid.NewGuid().ToString();         //非重复的随机字符串(十分钟内不能重复)
                string timestamp = TimeStamp.get10().ToString();  //当前时间戳(秒)
                //测试
                //string secretKey = "RhaDw4H0RUbWYyTxmRKM1eSeN0qyGLds";
                //string passid = "test_hosp";

                //正式
                //string secretKey = "4G9PvAy1xEkvgZJGZ0cNOacQZZYe2Bkg";
                //string passid = "dg_sc_yjyy";

                string secretKey = Global.inf.apiSecretKey;
                string passid = Global.inf.passid;
                //内容类型
                request.ContentType = "application/json";

                //签名
                string sTemp = timestamp + secretKey + nonce + timestamp;
                //Sha256 加密生成的签名 x-tif-signature = sha256(x-tif-timestamp + secretKey+ x-tif-nonce + xtif-timestamp)
                string signature = Encrypt.SHA256EncryptStr(sTemp);


                Global.writeLog($"nonce:{nonce}\ntimestamp:{timestamp}\nsecretKey:{secretKey}\npassid:{passid}\nsignature:{signature}");

                //增加头部信息
                request.Headers.Add("x-tif-paasid", passid);
                request.Headers.Add("x-tif-timestamp", timestamp);
                request.Headers.Add("x-tif-signature", signature);
                request.Headers.Add("x-tif-nonce", nonce);                

                //设置参数,并进行URL编码 
                string paraUrlCoded = JsonHelper.toJsonString(jsonInParam);
                byte[] payload;
                //将Json字符串转化为字节  
                payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);
                //设置请求的ContentLength   
                request.ContentLength = payload.Length;
                Stream writer;
                try
                {
                    writer = request.GetRequestStream();//获取用于写入请求数据的Stream对象
                }
                catch (Exception)
                {
                    writer = null;
                    errorCode = -100;
                    error = "连接服务器失败!";
                }
                //将请求参数写入流
                writer.Write(payload, 0, payload.Length);
                writer.Close();//关闭请求流
                               // String strValue = "";//strValue为http响应所返回的字符流
                               //发送请求并获取相应回应数据
                HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                //直到request.GetResponse()程序才开始向目标网页发送Post请求
                Stream responseStream = response.GetResponseStream();
                //创建本地文件写入流
                byte[] bArr = new byte[102400];
                int iTotalSize = 0;
                int size = responseStream.Read(bArr, 0, (int)bArr.Length);
                while (size > 0)
                {
                    iTotalSize += size;
                    fs.Write(bArr, 0, size);
                    size = responseStream.Read(bArr, 0, (int)bArr.Length);
                }
                fs.Close();
                responseStream.Close();
                dynamic joReturn = new JObject();
                joReturn.errorCode = errorCode;
                joReturn.errorMessage = error;
                joReturn.filePath = filePath;
                outputData = joReturn.ToString();
            }
            catch (Exception ex)
            {
                errorCode = -100;
                error = ex.Message;
                dynamic joReturn = new JObject();
                joReturn.errorCode = errorCode;
                joReturn.errorMessage = error;
                outputData = joReturn.ToString();
                return -1;
            }
            finally
            {
                Global.writeLog("DownloadCenterFile" + "(" + Global.curEvt.URL + ")", inputData, outputData);
            }
            return 0;
        }

        public int Init(ref string pErrMsg)
        {
            return 0;
        }

        public int UploadFile(string inputData, ref string outputData, ref string pErrMsg)
        {
            throw new NotImplementedException();
        }


        private string getResponseData(HttpWebResponse response)
        {
            string data = "";
            if (response != null)
            {
                Stream s = response.GetResponseStream();
                StreamReader sRead = new StreamReader(s,Encoding.GetEncoding("UTF-8"));
                data = sRead.ReadToEnd();
                sRead.Close();
                response.Close();
            }
            return data;
        }

    }
}