namespace OASystem.API.OAMethodLib.YouDaoAPI
{
    /// <summary>
    /// 有道API Tools
    /// </summary>
    public static class YouDaoApiTools
    {
        private static readonly HttpClient _httpClient = new() { BaseAddress = new Uri("https://openapi.youdao.com") };
        //private static readonly IHttpClientFactory _httpClientFactory;
        private static readonly string _appKey = "0fe3bc01e109ed36";    //应用ID
        private static readonly string _appSecret = "1f2x9TrqJfSBEJ8iH9GEFGgTyaYGjEry"; //应用密钥

        #region OCR 调用翻译
        public static async Task<string> GetOCR_ReTrans(string txt)
        {
            var data = await GetReTrans(txt);
            string str;
            if (data == null && data.Code != 0)
                str = txt;
            else
                str = data.Data as string;

            return str;
        }
        #endregion

        /// <summary>
        /// 有道翻译
        /// 默认 中=>英
        /// </summary>
        /// <param name="txt">待翻译的文本</param>
        /// <param name="from">源语言</param>
        /// <param name="to">目标语言</param>
        /// <returns></returns>
        public static async Task<Result> GetReTrans(string txt, string from = "zh-CHS", string to = "en")
        {
            var result = new Result();
            #region MyRegion
            if (string.IsNullOrEmpty(txt))
            {
                result.Msg = "待翻译文本为空!";
                return result;
            }

            #endregion

            string url = string.Format("/api");

            #region 请求参数处理

            string q = txt;
            //input的计算方式为:input=q前10个字符 + q长度 + q后10个字符(当q长度大于20)或 input=q字符串(当q长度小于等于20);
            string input = q.Length <= 20 ? q : q.Substring(0, 10) + q.Length + q.Substring(q.Length - 10, 10);
            string salt = DateTime.Now.Millisecond.ToString();
            string curtime = GetUTCTime(true).ToString(); //UTC秒时间戳
            //sign = sha256(应用ID + input + salt + curtime + 应用密钥);
            string signStr = string.Format("{0}{1}{2}{3}{4}", _appKey, input, salt, curtime, _appSecret);
            string sign = SHA256EncryptString(signStr);
            #endregion

            var reqData = new FormUrlEncodedContent(
                            new List<KeyValuePair<string, string>>()
                            {
                                //new("q",System.Web.HttpUtility.UrlEncode(q, Encoding.UTF8)),//待翻译文本  必须是UTF-8编码
                                new("q",q),             //待翻译文本  必须是UTF-8编码
                                new("from",from),       //源语言
                                new("to",to),           //目标语言
                                new("appKey",_appKey),  //应用ID
                                new("salt",salt),       //UUID
                                new("sign",sign),       //签名 
                                new("signType","v3"),   //签名类型
                                new("curtime",curtime), //TUC 时间戳
                            });

            var reTransReq = await _httpClient.PostAsync(url, reqData);
            if (reTransReq.IsSuccessStatusCode)
            {
                var strResponse = await reTransReq.Content.ReadAsStringAsync();
                var strResponse1 = System.Web.HttpUtility.UrlDecode(strResponse, System.Text.Encoding.UTF8);

                var trans = JsonConvert.DeserializeObject<dynamic>(strResponse1);
                string errorCode = trans["errorCode"].ToString();
                if (errorCode == "0")
                {
                    result.Code = 0;
                    var translation = JsonConvert.DeserializeObject<List<string>>(trans["translation"].ToString());
                    result.Msg = string.Format(@"成功!");
                    result.Data = translation[0];
                }
                else
                {
                    result.Msg = string.Format(@"有道翻译API [Error:{0}]", errorCode);
                }
            }
            else
            {
                result.Msg = "接口请求失败!";
            }


            return result;
        }

        #region SHA256加密
        /// <summary>
        /// SHA256加密
        /// </summary>
        /// <param name="data"></param>
        public static string SHA256EncryptString(string data)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(data);
            byte[] hash = SHA256.Create().ComputeHash(bytes);

            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                builder.Append(hash[i].ToString("x2"));
            }
            return builder.ToString();
        }

        /// <summary>
        /// SHA256加密
        /// </summary>
        /// <param name="StrIn">待加密字符串</param>
        /// <returns>加密数组</returns>
        public static Byte[] SHA256EncryptByte(string StrIn)
        {
            using var sha256 = SHA256.Create();
            var Asc = new ASCIIEncoding();
            var tmpByte = Asc.GetBytes(StrIn);
            var EncryptBytes = sha256.ComputeHash(tmpByte);
            return EncryptBytes;
        }
        #endregion

        #region UTC时间戳
        /// <summary>
        /// 获取utc时间
        /// </summary>
        /// <param name="type">true 秒 flase 毫秒</param>
        /// <returns></returns>
        public static long GetUTCTime(bool type)
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return type ? Convert.ToInt64(ts.TotalSeconds) : Convert.ToInt64(ts.TotalMilliseconds);
        }

        ///// <summary>
        ///// 将当前时间戳转换至Datetime
        ///// </summary>
        ///// <param name="timeStamp"></param>
        ///// <returns></returns>
        //public static DateTime ConvertUTCToDateTime(long timeStamp)
        //{
        //    DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); // 当地时区
        //    DateTime dt = startTime.AddSeconds(timeStamp);
        //    return dt;
        //}

        ///// <summary>
        ///// 把datetime转utc时间戳
        ///// </summary>
        ///// <param name="time"></param>
        ///// <returns></returns>
        //public static int ConvertDateTimeToUTC(DateTime time)
        //{
        //    double intResult = 0;
        //    DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
        //    intResult = (time - startTime).TotalSeconds;
        //    return (int)intResult;
        //}
        #endregion

    }
}