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.anserx
{
    public class Api : IBaseApi
    {
        public string ServiceName => "anserx";

        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 Task<List<string>> Confims(List<OrderConfimRequest> order, Logistics_Channel channel)
        {
            throw new NotImplementedException();
        }

        public async Task<UploadResult> DataUpload(Order_Order order, List<Order_OrderGoods> goods, Logistics_Channel channel, ExtendArg arg)
        {
            var request = CreateOrder(order, goods, channel);
            var r = Send("createOrder", request, channel);
            var orderResult = Newtonsoft.Json.JsonConvert.DeserializeObject<OrderResut>(r);
            if (orderResult.code == 0)
            {
                return new UploadResult
                {
                    IsSuccess = true,
                    TrackingNumber = orderResult.data.waybillNo,
                    ServiceOrderNumber = orderResult.data.deliveryNo,
                    ServiceOrderNumber2 = orderResult.data.customerOrderNo
                };
            }
            else
            {
                throw new Exception(orderResult.msg);
            }

        }
        //如果好用，请收藏地址，帮忙分享。
        public class OrderData
        {
            /// <summary>
            /// 
            /// </summary>
            public string customerOrderNo { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string waybillNo { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string deliveryNo { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string sortingCode { get; set; }
        }

        public class OrderResut
        {
            /// <summary>
            /// 
            /// </summary>
            public int code { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string msg { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public OrderData data { get; set; }
        }

        public Order CreateOrder(Order_Order o, List<Order_OrderGoods> goods, Logistics_Channel channel)
        {
            if (goods.All(x => x.Weight == 0))
            {
                var avgWeight = Math.Ceiling(o.CustomerWeight / (goods.Sum(x => x.Quantity) / 1.0));
                goods.ForEach(x => x.Weight = (int)avgWeight);
            }
            Order request = new Order
            {
                shipper = new Shipper
                {
                    shipperAddress = channel.SenderStreet,
                    shipperCity = channel.SenderCity,
                    shipperCompany = channel.SenderCompany,
                    shipperCountry = channel.SenderCountryCode,
                    shipperDistrict = "",
                    shipperDoorplate = "",
                    shipperEmail = channel.SenderEmail,
                    shipperName = channel.SenderName,
                    shipperPhone = channel.SenderPhone,
                    shipperPostcode = channel.SenderZipCode,
                    shipperProvince = channel.SenderState,
                    shipperStreet = channel.SenderStreet
                },
                codCurrency = string.Empty,
                customerOrderNo = o.SystemNo.Replace("XYYEX", "A"),
                declareCurrency = goods.First().DeclareCurrency,
                goodsCategory = 15,
                taxPayMode = 10,
                logisticsProductCode = "LP00002903",
                parcelType = 10,
                orderDeclareList = goods.Select(x => new OrderDeclareListItem
                {
                    chineseName = x.CnName,
                    englishName = x.EnName,
                    hsCode = x.HsCode,
                    unitDeclarePriceD = x.DeclareFee,
                    quantity = x.Quantity,
                    unitNetWeightD = x.Weight / 1000.0m
                }).ToList(),
                packageList = new List<PackageListItem>
                {
                    new PackageListItem
                    {
                        packageWeightD =  o.CustomerWeight/1000.0m
                    }
                },
                consignee = new Consignee
                {
                    consigneeAddress = o.ReceiverStreet,
                    consigneeCity = o.ReceiverCity,
                    consigneeCountry = o.ReceiverCountryCode,
                    consigneeName = o.ReceiverName,
                    consigneePhone = o.ReceiverPhone,
                    consigneePostcode = o.ReceiverZipCode,
                    consigneeProvince = o.ReceiverState
                }
            };

            return request;
        }

        /// <summary>
        /// apiKey：57ab2f4ccc7244abbb12ad41e00976eb
        /// apiSecret：3fea81dc49ee41319e3903e62bfcb447
        /// userToken：6863f4547eae43f78147e6e09448f3c9
        /// 下单action: createOrder
        /// </summary>
        /// <param name="message"></param>
        /// <param name="o"></param>
        /// <returns></returns>
        public string Send(string action, object o, Logistics_Channel channel)
        {
            string timestampValue = DateTime.Now.ToFileTimeUtc().ToString();
            string url = channel.ApiHost + action;

            string apiKey = "9579097d3f724d32b7bdd9d215e6e35e";
            string apiSecret = "a6c7934f58844cf6b8a7d181965668d4";
            string usertoken = "9b66521e2fbd4f6a9dd673b483ce4e04";
            string body = Newtonsoft.Json.JsonConvert.SerializeObject(o);
            string paramstr = apiKey + apiSecret + usertoken + timestampValue + body;
            string sign = Encryption.Md532(paramstr);

            RestSharp.RestRequest request = new RestSharp.RestRequest(RestSharp.Method.POST);
            RestSharp.RestClient client = new RestSharp.RestClient(url);
            request.AddHeader("apiKey", apiKey);
            //request.AddHeader("apiSecret", apiSecret);
            request.AddHeader("usertoken", usertoken);
            request.AddHeader("timestamp", timestampValue);
            request.AddHeader("signature", sign);
            request.AddHeader("Content-Type", "application/json;charset=UTF-8");
            request.AddJsonBody(body);
            var response = client.Execute(request);
            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                return response.Content;
            }
            else
            {
                return response.ErrorMessage + ":" + response.Content;
            }



            //sign

        }


        public async Task<byte[]> DrawPdfLabel(UploadResult result, Logistics_Channel channel, Order_Order order, List<Order_OrderGoods> orderGoods)
        {
            var request = new { mergePdf = 1, nos = new string[] { result.ServiceOrderNumber2 } };
            var respones = Send("label", request, channel);
            var labelR = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(respones);
            if (labelR.code == 0)
            {
                string labelUrl = labelR.labelUrl;
                System.Net.WebClient client = new System.Net.WebClient();
                byte[] data = null;
                int minSize = 3000;
                for (var i = 0; i < 3; i++)
                {
                    data = client.DownloadData(labelUrl);
                    if (data.Length > 3000)
                        return data;
                }
                throw new Exception("面单下载失败" + labelUrl);

            }
            else
            {
                throw new Exception(labelR.msg);
            }
        }

        public Task<string> GetTrackingNumber(string SystemNo, string TrackingNumber, string ServiceOrderNo, Logistics_Channel channel)
        {
            throw new NotImplementedException();
        }

        //如果好用，请收藏地址，帮忙分享。
        public class Shipper
        {
            /// <summary>
            /// 
            /// </summary>
            public string shipperName { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string shipperCompany { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string shipperPhone { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string shipperEmail { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string shipperCountry { get; set; }
            /// <summary>
            /// 广东
            /// </summary>
            public string shipperProvince { get; set; }
            /// <summary>
            /// 广州
            /// </summary>
            public string shipperCity { get; set; }
            /// <summary>
            /// 白云
            /// </summary>
            public string shipperDistrict { get; set; }
            /// <summary>
            /// 汇金广场A座
            /// </summary>
            public string shipperAddress { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string shipperPostcode { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string shipperDoorplate { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string shipperStreet { get; set; }
        }

        public class Consignee
        {
            /// <summary>
            /// 
            /// </summary>
            public string consigneeName { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string consigneePhone { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string consigneeProvince { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string consigneeAddress { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string consigneeCity { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string consigneeCountry { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string consigneePostcode { get; set; }
        }

        public class PackageListItem
        {

            /// <summary>
            /// 
            /// </summary>
            public decimal packageWeightD { get; set; }
        }

        public class OrderDeclareListItem
        {
            public decimal unitNetWeightD { get; set; }
            /// <summary>
            /// 学校发的
            /// </summary>
            public string chineseName { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string englishName { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public int quantity { get; set; }
            public decimal unitDeclarePriceD { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string hsCode { get; set; }
        }

        public class Order
        {
            /// <summary>
            /// 
            /// </summary>
            public string customerOrderNo { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string logisticsProductCode { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public int taxPayMode { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public int parcelType { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public int goodsCategory { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string declareCurrency { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string codCurrency { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public Shipper shipper { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public Consignee consignee { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public List<PackageListItem> packageList { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public List<OrderDeclareListItem> orderDeclareList { get; set; }
        }
    }
}
