using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XYY.Common.Standard.String;
using XYY.Model.Standard.Channel;
using XYY.Model.Standard.Order;
using XYY.Service.Standard.ChannelApi.Base;

namespace XYY.Service.Standard.ChannelApi.JiTu
{
    public class Api : IBaseApi
    {
        public string ServiceName => "JiTu";
        int maxRetryCount = 3;
        public Task<List<BagDeclareErrosResult>> BagDeclare(BagDeclareRequest bagDeclareRequest)
        {
            throw new NotImplementedException();
        }

        public void CannelOrders(List<string> systemNO)
        {
            throw new NotImplementedException();
        }

        public void CannelOrdersByModel(logistics_ChannelCancel logistics_ChannelCancel)
        {
            throw new NotImplementedException();
        }

        public async Task<List<string>> Confims(List<OrderConfimRequest> order, Logistics_Channel channel)
        {
            List<string> errors = new List<string>();
            string url = @"https://api.yl-scm.com/yl-crs-openplatform-api/order/update/weight";
            foreach (var item in order)
            {
                var obj = new
                {
                    billCode = item.ServicesOrderNo,
                    weight = item.OPWeight / 1000.0m
                };
                string json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
                var resJson = Send(channel.ApiKey, channel.ApiSecret.Split(',')[0]
                , json, "UPDATEORDERWEIGHT", url);
                WeightComfigResult result = Newtonsoft.Json.JsonConvert.DeserializeObject<WeightComfigResult>(resJson);
                if (result.success != "true")
                {
                    errors.Add(item.TrackingNumber);
                }
            }
            return errors;
        }

        UploadResult CreateOrderByApi(Order_Order order, List<Order_OrderGoods> goods, Logistics_Channel channel, bool changeOrderNumber = false)
        {
            var request = ConvertOrder(order, goods, channel, changeOrderNumber);
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(request);
            var resJson = Send(channel.ApiKey, channel.ApiSecret.Split(',')[0]
                , json, "ORDERCREATE", "https://api.yl-scm.com/yl-crs-openplatform-api/europe/order/create");
            CreateOrderResult result = Newtonsoft.Json.JsonConvert.DeserializeObject<CreateOrderResult>(resJson);
            if (result.responseitems.Count > 0)
            {
                if (result.responseitems[0].success)
                {
                    return new UploadResult
                    {
                        IsSuccess = true,
                        TrackingNumber = result.responseitems[0].trackingNo ?? result.responseitems[0].mailno,
                        ServiceOrderNumber = result.responseitems[0].mailno
                    };
                }
                else
                {
                    if (resJson.Contains("订单号重复"))
                    {
                        Random ran = new Random();
                        int n = ran.Next(1, 99);
                        order.SystemNo += n.ToString();
                        var rs2 = CreateOrderByApi(order, goods, channel, false);
                        return rs2;
                        //throw new Exception($"下单失败" + resJson);
                    }
                    else { throw new Exception($"下单失败" + resJson); }
                    //throw new Exception($"下单失败" + resJson);
                }
            }
            else
            {
                throw new Exception($"下单返回结果解析错误{resJson}");
            }
        }

        public async Task<UploadResult> DataUpload(Order_Order order, List<Order_OrderGoods> goods, Logistics_Channel channel, ExtendArg arg)
        {
            var rs = await Task.Run<UploadResult>(() =>
            {
                var result = CreateOrderByApi(order, goods, channel);
                return result;
            });
            return rs;
        }



        private static CreateOrderRequest ConvertOrder(Order_Order order, List<Order_OrderGoods> goods, Logistics_Channel channel, bool changeOrderNumber = false)
        {
            System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"\w+( +)[\u4e00-\u9fa5]+");
            goods.ForEach(x =>
            {
                if (regex.IsMatch(x.CnName))
                {
                    x.CnName = x.CnName.Replace(regex.Match(x.CnName).Groups[1].Value, "");
                }
            });
            if (goods.Any(x => x.Weight == 0))
            {
                //平摊物品重量
                int goodsQty = goods.Sum(x => x.Quantity);
                decimal avgWeight = Math.Floor(order.CustomerWeight / (decimal)goodsQty);
                goods.ForEach(x => x.Weight = (int)avgWeight);


            }
            string r = "";
            switch (order.ChannelId)
            {
                case 411:
                    r = "RLTEX";
                    break;
                case 447:
                    r = "SREX";
                    break;
            }
            string refOrederNo = "R" + order.SystemNo.Replace("XYYEX", r);
            if (changeOrderNumber)
            {
                refOrederNo += "1";
            }


            CreateOrderRequest request = new CreateOrderRequest
            {
                customerid = channel.ApiSecret.Split(',')[1],
                txlogisticid = refOrederNo,
                ordertype = "1",
                weight = (order.CustomerWeight / 1000.0m).ToString("0.000"),
                servicetype = "1",
                goodstype = "1",
                paytype = "1",
                createordertime = DateTime.Now.ToString_yyyyMMddHHmmss(),
                transport = "空运",
                routeid = channel.ServiceChannelCode,
                sender = new Sender
                {
                    city = channel.SenderCity,
                    address = channel.SenderStreet,
                    area = channel.SenderCounty,
                    mailbox = channel.SenderEmail,
                    mobile = channel.SenderPhone,
                    postcode = channel.SenderZipCode,
                    name = channel.SenderName,
                    prov = channel.SenderState
                },
                receiver = new Receiver
                {
                    city = order.ReceiverCity,
                    countrycode = order.ReceiverCountryCode,
                    address = order.ReceiverStreet,
                    mobile = order.ReceiverPhone,
                    name = order.ReceiverName,
                    postcode = order.ReceiverZipCode,
                    prov = order.ReceiverState
                },
                items = goods.Select(x =>
                {
                    return new ItemsItem
                    {
                        itemname = x.CnName,
                        englishName = x.EnName,
                        pricecurrency = x.DeclareCurrency,
                        number = x.Quantity.ToString(),
                        itemvalue = x.DeclareFee.ToString("0.00"),
                        weight = ((x.Weight == 0 ? 1 : x.Weight) / 1000.0m).ToString("0.000"),
                        hsCode = x.HsCode
                    };
                }).ToList()
            };
            return request;
        }

        public string Send(string key, string eccompanyid, string json, string action, string url)
        {
            string sign = GetSign(key, json);
            var client = new RestSharp.RestClient(url);
            client.RemoteCertificateValidationCallback =
           (sender, certificate, chain, sslPolicyErrors) => true;
            var reqeust = new RestSharp.RestRequest(RestSharp.Method.POST);
            reqeust.AddParameter("logistics_interface", json);
            reqeust.AddParameter("data_digest", sign);
            reqeust.AddParameter("msg_type", action);
            reqeust.AddParameter("eccompanyid", eccompanyid);
            var response = client.Execute(reqeust);
            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                return response.Content;
            }
            else
            {
                throw new Exception("请求失败，失败原因" + response.ErrorMessage + "," + response.Content);
            }

        }

        public string GetSign(string key, string json)
        {
            string md5 = Encryption.Md532(json + key);
            if (!string.IsNullOrEmpty(md5))
            {
                md5 = md5.ToLower();
                byte[] bytes = Encoding.Default.GetBytes(md5);
                return Convert.ToBase64String(bytes);
            }
            else
            {
                throw new Exception("加密失败，MD5数据为空");
            }

        }

        public async Task<byte[]> DrawPdfLabel(UploadResult result, Logistics_Channel channel, Order_Order order, List<Order_OrderGoods> orderGoods)
        {
            var request = new
            {
                billcode = result.ServiceOrderNumber
            };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(request);
            for (int i = 0; i < 30; i++)
            {
                var resJson = Send(channel.ApiKey, channel.ApiSecret.Split(',')[0], json, "ROTAPRINT",
                    "https://api.yl-scm.com/yunlu-order-web/rotaPrin/rotaPrintAction!getPrintUrl.action");
                var r = Newtonsoft.Json.JsonConvert.DeserializeObject<GetLabelResult>(resJson);
                if (r.responseitems.Count > 0)
                {
                    if (r.responseitems[0].success)
                    {
                        string url = r.responseitems[0].rotaprinturl;
                        var webClient = new System.Net.WebClient();
                        return webClient.DownloadData(url);
                    }
                    else
                    {
                        if (r.responseitems[0].reason == "B115b")
                        {
                            System.Threading.Thread.Sleep(3 * 1000);
                            continue;
                        }
                        else
                        {
                            throw new Exception($"下载面单失败" + r.responseitems[0].reason + r.responseitems[0].desc);
                        }
                    }
                }
                else
                {
                    throw new Exception($"下单返回结果解析错误{resJson}");
                }
            }
            throw new Exception($"下载面单失败" + "，面单暂未生成");
        }

        public async Task<string> GetTrackingNumber(string SystemNo, string TrackingNumber, string ServiceOrderNo, Logistics_Channel channel)
        {
            string url = "https://api.yl-scm.com/yunlu-order-web/order/orderAction!queryOrderInfo.action";
            string action = "QUERYORDER";
            var obj = new
            {
                customerid = channel.ApiSecret.Split(',')[1],
                command = 2,
                serialnumber = ServiceOrderNo,
                status = 1,
                ordertype = 1,
                country = "US"
            };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
          
            var resJson = Send(channel.ApiKey, channel.ApiSecret.Split(',')[0]
                , json, action, url);
            GetOrderResult result = Newtonsoft.Json.JsonConvert.DeserializeObject<GetOrderResult>(resJson);
            return result.responseitems[0].orderList[0].endTrackingNo;

        }
    }
}
