using DeviceRepair.Models;
using DeviceRepair.Models.Common;
using DeviceRepair.Utils;
using System;
using System.Data;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http;
using System.Xml;

namespace DeviceRepair.Api.CustomAttribute
{
    public class HttpAuthorizeAttribute : AuthorizeAttribute
    {
        private static readonly string passKey = "^2020#!_@MaYonglong@_!#2021^";
        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            APIResponseData Rtn = new APIResponseData { Code = -1, Message = "当前访问未授权！" };
            try
            {
                if (actionContext.Request.Headers.Contains("auth"))
                {
                    // 获取自定义头部的值
                    string token = actionContext.Request.Headers.GetValues("auth").FirstOrDefault();

                    if (!string.IsNullOrWhiteSpace(token))
                    {
                        try
                        {
                            TokenModel userInfo = DecodeToObject(token);
                            if (userInfo != null)
                                return;
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                    }
                }
                else if (actionContext.Request.Headers.Contains("sfc"))
                {
                    string desToken = actionContext.Request.Headers.GetValues("sfc").FirstOrDefault();
                    if (!string.IsNullOrWhiteSpace(desToken))
                    {
                        try
                        {
                            string token = Utils.Security.DESEncrypt.Decrypt(desToken);
                            SFCTokenModel model = Newtonsoft.Json.JsonConvert.DeserializeObject<SFCTokenModel>(token);
                            if (
                                model != null && !string.IsNullOrWhiteSpace(model.inParams) &&
                                !string.IsNullOrWhiteSpace(model.LoginCode) && !string.IsNullOrWhiteSpace(model.Password)
                                )
                            {
                                if (SfcUserValidate(model.LoginCode, model.Password, model.inParams))
                                {
                                    return;
                                }
                            }
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                    }
                }

                //IEnumerable<string> token;
                //if (actionContext.Request.Headers.TryGetValues("auth", out token))
                //{
                //    if (token != null && token.Count() > 0)
                //    {
                //        try
                //        {
                //            TokenModel userInfo = null;
                //            foreach (string item in token)
                //            {
                //                userInfo = DecodeToObject(item);
                //                if (userInfo != null)
                //                    break;
                //            }

                //            if (userInfo != null)
                //                return;
                //        }
                //        catch (Exception ex)
                //        {
                //            throw ex;
                //        }
                //    }
                //    return;
                //}
                //else if (actionContext.Request.Headers.TryGetValues("inParams", out token))
                //{
                //    if (token != null && token.Count() > 0)
                //    {
                //        try
                //        {
                //            IEnumerable<string> LoginCode;
                //            IEnumerable<string> Password;
                //            if (actionContext.Request.Headers.TryGetValues("LoginCode", out LoginCode) &&
                //                actionContext.Request.Headers.TryGetValues("Password", out Password) &&
                //                LoginCode != null && LoginCode.Count() > 0
                //                    && Password != null && Password.Count() > 0)
                //            {
                //                string inParams = string.Empty;
                //                string lc = string.Empty;
                //                string pwd = string.Empty;

                //                foreach (string item in token)
                //                {
                //                    if (!string.IsNullOrWhiteSpace(item))
                //                    {
                //                        inParams = item;
                //                    }
                //                }

                //                foreach (string item in LoginCode)
                //                {
                //                    if (!string.IsNullOrWhiteSpace(item))
                //                    {
                //                        lc = item;
                //                    }
                //                }

                //                foreach (string item in Password)
                //                {
                //                    if (!string.IsNullOrWhiteSpace(item))
                //                    {
                //                        pwd = item;
                //                    }
                //                }

                //                bool isSuccess = SfcUserValidate(lc, pwd, inParams);
                //                if (isSuccess)
                //                    return;
                //            }
                //        }
                //        catch (Exception ex)
                //        {
                //            throw ex;
                //        }
                //    }
                //    return;
                //}

                actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized) { Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(Rtn), Encoding.UTF8, "application/json") };
                return;
            }
            catch (Exception ex)
            {
                Rtn.Message += Environment.NewLine + ex.Message;
                actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized) { Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(Rtn), Encoding.UTF8, "application/json") };
            }
        }



        /// <summary>
        /// 验证SFC账户密码
        /// </summary>
        /// <param name="LoginCode"></param>
        /// <param name="Password"></param>
        /// <returns></returns>
        public bool SfcUserValidate(string LoginCode, string Password, string inParams)
        {
            try
            {
                string SFCWebServiceUrl = Utils.Config.Configurations.Properties.SFCWebServiceUrl;
                bool isSuccess = false;
                byte[] password = Encoding.Unicode.GetBytes(LoginCode);
                Array.Reverse(password);
                string pass64 = Convert.ToBase64String(password);
                if (pass64.Length < 10)
                    pass64 += "YeT+=fue";

                StringBuilder builder = new StringBuilder();
                builder.AppendLine($"<?xml version=\"1.0\" encoding=\"utf-8\"?>");
                builder.AppendLine($"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">");
                builder.AppendLine($"  <soap:Header>");
                builder.AppendLine($"   <SvcAuthentication xmlns=\"http://www.TechScan.cn/\">");
                builder.AppendLine($"       <Password>{pass64}</Password>");
                builder.AppendLine($"       <Username>{LoginCode}</Username>");
                builder.AppendLine($"   </SvcAuthentication>");
                builder.AppendLine($"   </soap:Header>");
                builder.AppendLine($"   <soap:Body>");
                builder.AppendLine($"      <UserLogin xmlns=\"http://www.TechScan.cn/\">");
                builder.AppendLine($"         <userCode>{LoginCode}</userCode>");
                builder.AppendLine($"         <pwd>{Password}</pwd>");
                builder.AppendLine($"         <inParams>{inParams}</inParams>");
                builder.AppendLine($"      </UserLogin>");
                builder.AppendLine($"   </soap:Body>");
                builder.AppendLine($"</soap:Envelope>");

                using (var client = new HttpClient())
                {
                    var content = new StringContent(builder.ToString(), Encoding.UTF8, "text/xml");
                    var request = new HttpRequestMessage(HttpMethod.Post, $"{SFCWebServiceUrl}/SfcService.asmx");
                    request.Content = content;

                    var response = client.SendAsync(request).Result;
                    if (response.IsSuccessStatusCode)
                    {
                        string stringRtn = response.Content.ReadAsStringAsync().Result;

                        XmlDocument doc = new XmlDocument();
                        doc.LoadXml(stringRtn);
                        XmlNode Node = doc.DocumentElement["soap:Body"]["UserLoginResponse"]["UserLoginResult"]["Code"].LastChild;

                        if (Node.Value == "0")
                        {
                            Node = doc.DocumentElement["soap:Body"]["UserLoginResponse"]["btResults"].LastChild;
                            byte[] bytes = Convert.FromBase64String(Node.Value);
                            DataSet ds = bytes.ExactDataSet();
                            isSuccess = ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0;
                        }
                    }

                }
                return isSuccess;
            }
            catch (Exception)
            {
                throw;
            }
        }


        /// <summary>
        /// 通过token反序列化到对象
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public TokenModel DecodeToObject(string token)
        {
            TokenModel jsonData = JWT.JsonWebToken.DecodeToObject<TokenModel>(token, passKey);
            return jsonData;
        }
    }
}