using Newtonsoft.Json;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using XYY.Data.Standard.Order;
using XYY.Model.Standard.Channel;
using XYY.Model.Standard.Order;
using XYY.Service.Standard.ChannelApi.Base;
using static XYY.Service.Standard.ChannelApi.Itdida.ItdidaApi;

namespace XYY.Service.Standard.ChannelApi.K5
{
    public class Api : IBaseApi
    {
        public string ServiceName => "K5";
        /// <summary>
        /// 直接出面单的渠道
        /// </summary>
        public List<int> OrderType4 => new List<int>() { 364, 363, 555, 554, 553, 552 };
        /// <summary>
        /// pak类型的渠道
        /// </summary>
        public List<int> GoodsTypePAK => new List<int>() { 363, 555, 554 };
        IOrder_OrderPrintQtyRepository _order_OrderPrintQtyRepository;
        public Api(IOrder_OrderPrintQtyRepository order_OrderPrintQtyRepository)
        {
            _order_OrderPrintQtyRepository = order_OrderPrintQtyRepository;
        }
        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)
        {

            if (order.ReceiverCountryCode == "US")
            {
                string[] Remote = new string[] { "AK", "HI", "GU", "AS", "MP", "PR", "VI", "AE", "AP" };

                Dictionary<string, string> pairs = new Dictionary<string, string>
                {
                    { "Washington", "WA" },
                    { "Oregon", "OR" },
                    { "California", "CA" },
                    { "Nevada", "NV" },
                    { "Idaho", "ID" },
                    { "Utah", "UT" },
                    { "Arizona", "AZ" },
                    { "Montana", "MT" },
                    { "Wyoming", "WY" },
                    { "Colorado", "CO" },
                    { "New Mexico", "NM" },
                    { "Wisconsin", "WI" },
                    { "Illinois", "IL" },
                    { "Tennessee", "TN" },
                    { "Mississippi", "MS" },
                    { "Michigan", "MI" },
                    { "Indiana", "IN" },
                    { "Kentucky", "KY" },
                    { "Alabama", "AL" },
                    { "Ohio", "OH" },
                    { "West Virginia", "WV" },
                    { "Virginia", "VA" },
                    { "North Carolina", "NC" },
                    { "South Carolina", "SC" },
                    { "Georgia", "GA" },
                    { "North Dakota", "ND" },
                    { "South Dakota", "SD" },
                    { "Nebraska", "NE" },
                    { "Kansas", "KS" },
                    { "Oklahoma", "OK" },
                    { "Texas", "TX" },
                    { "Minnesota", "MN" },
                    { "Iowa", "IA" },
                    { "Missouri", "MO" },
                    { "Arkansas", "AR" },
                    { "Louisiana", "LA" },
                    { "Florida", "FL" },
                    { "Pennsylvania", "PA" },
                    { "New York", "NY" },
                    { "Washington D. C.", "DC" },
                    { "Maryland", "MD" },
                    { "Delaware", "DE" },
                    { "New Jersey", "NJ" },
                    { "Connecticut", "CT" },
                    { "Rhode Island", "RI" },
                    { "Massachusetts", "MA" },
                    { "Maine", "ME" },
                    { "New Hampshire", "NH" },
                    { "Vermont", "VT" }
                };

                if (!pairs.Keys.Any(x => x.Equals(order.ReceiverState, StringComparison.CurrentCultureIgnoreCase))
                        && !pairs.Values.Any(x => x.Equals(order.ReceiverState, StringComparison.CurrentCultureIgnoreCase))
                        )
                {
                    if (pairs.Keys.Any(x => x.Equals(order.ReceiverCity, StringComparison.CurrentCultureIgnoreCase)))
                    {
                        string state = order.ReceiverState;
                        order.ReceiverState = pairs.Where(x => x.Key.Equals(order.ReceiverCity, StringComparison.CurrentCultureIgnoreCase)).First().Value;
                        order.ReceiverCity = state;
                    }
                    else if (pairs.Values.Any(x => x.Equals(order.ReceiverCity, StringComparison.CurrentCultureIgnoreCase)))
                    {
                        string state = order.ReceiverState;
                        order.ReceiverState = order.ReceiverCity;
                        order.ReceiverCity = order.ReceiverState;
                    }
                }
                else if (pairs.Keys.Any(x => x.Equals(order.ReceiverState, StringComparison.CurrentCultureIgnoreCase)))
                {
                    order.ReceiverState = pairs.Where(x => x.Key.Equals(order.ReceiverState, StringComparison.CurrentCultureIgnoreCase)).First().Value;
                }
            }

            //test
            //channel.ApiHost = "http://enyuan.kingtrans.net/";
            string action = "PostInterfaceService?method=createOrder";
            if (OrderType4.Contains(channel.Id))// channel.PublicName == "MHD-Fedex-PAK" || channel.PublicName == "MHD-Fedex-PKG"
            {
                goods.ForEach(x =>
                {
                    if (x.CnName != "手链"
                    && !x.CnName.StartsWith("100%")
                    && x.CnName != "耳环"
                    && x.CnName != "项链"
                    && !x.CnName.Contains("鞋"))
                    {
                        x.EnName = "100% polyester" + x.EnName;
                        x.CnName = "100% 聚酯" + x.CnName;
                    }
                });
                //合并物品
                List<Order_OrderGoods> t = new List<Order_OrderGoods>();
                foreach (var item in goods.CopyList<Order_OrderGoods>())
                {
                    if (t.Any(x => x.CnName == item.CnName && x.EnName == item.EnName && x.HsCode == item.HsCode && x.DeclareFee == item.DeclareFee))
                    {
                        t.First(x => x.CnName == item.CnName && x.EnName == item.EnName && x.HsCode == item.HsCode && x.DeclareFee == item.DeclareFee).Quantity += item.Quantity;
                    }
                    else
                    {
                        t.Add(item);
                    }
                }

                goods = t;
            }


            //channel.ApiKey = "0015";
            //channel.ApiSecret = "ZW55dWFu4SLizN78O8C0FH45qgbS";
            //channel.ServiceChannelCode = "035";
            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);

            }
            OrderRequest orderRequest = new OrderRequest
            {
                Verify = new Verify
                {
                    Clientid = channel.ApiKey,
                    Token = channel.ApiSecret
                },
                OrderType = OrderType4.Contains(channel.Id) ? "4" : "1",//channel.PublicName == "MHD-Fedex-PAK" || channel.PublicName == "MHD-Fedex-PKG"
                OrderDatas = new List<OrderDatasItem> {
                    new OrderDatasItem
                    {
                        CustomerNumber = order.SystemNo + "-" + _order_OrderPrintQtyRepository.GetPackagePrintQty(order.SystemNo),
                        ChannelCode =   channel.ServiceChannelCode,
                        CountryCode = order.ReceiverCountryCode,
                        GoodsType =GoodsTypePAK.Contains(channel.Id)  ?"PAK":"WPX",//channel.PublicName == "MHD-Fedex-PAK"
                        TotalWeight = (order.CustomerWeight/1000.0).ToString(),
                        TotalValue = goods.Sum(x=>x.DeclareFee*x.Quantity).ToString(),
                        Number ="1",
                        Volumes = new List<VolumesItem>
                        {
                            new VolumesItem
                            {
                                Weight = (order.CustomerWeight/1000.0).ToString("0.000"),
                                Number = "1",
                                Height =   !GoodsTypePAK.Contains(channel.Id) ? order.Height.ToString():"0",//channel.PublicName == "MHD-Fedex-PKG"
                                Width =   !GoodsTypePAK.Contains(channel.Id) ? order.Width.ToString():"0",
                                Length =   !GoodsTypePAK.Contains(channel.Id)? order.Length.ToString():"0",
                                //  Height =   channel.PublicName == "MHD-Fedex-PKG" ? "10":"0",
                                //Width =   channel.PublicName == "MHD-Fedex-PKG" ? "10":"0",
                                //Length =   channel.PublicName == "MHD-Fedex-PKG" ? "10":"0",
                            }
                        },
                        Recipient = new Recipient
                        {
                            Name = order.ReceiverName,
                            Company = order.ReceiverName,
                            City = order.ReceiverCity,
                            Addres1 = order.ReceiverStreet,
                            Tel = order.ReceiverPhone,
                            Province = order.ReceiverState,
                            Post=order.ReceiverZipCode,
                            Email=order.ReceiverEmail
                        },
                        FeeInfo = new FeeInfo
                        {
                            IsPaperLess = "1"
                        },
                        FeePayData = new FeePayData
                        {
                             FeePayType="PP"
                        },
                        TaxPayData = new TaxPayData
                        {
                            TaxPayType ="CC"
                        },
                        OrderItems = goods.Select(x=>new OrderItemsItem {
                           Cnname=   x.CnName,
                           Enname=x.EnName,
                           Price =x.DeclareFee.ToString(),
                           SingleWeight = (x.Weight/1000).ToString(),
                           Num = x.Quantity.ToString(),
                           CustomsCode = x.HsCode,
                           Money = x.DeclareCurrency
                        }).ToList()
                    },
                },
            };
            if (channel.PublicName == "MHD-Fedex-PAK" || channel.PublicName == "MHD-Fedex-PKG")
            {
                //orderRequest.OrderDatas[0].Sender = new Sender
                //{
                //    Name= "David Zhai",
                //    Company= "KOOTION",
                //    Addres = "6162, BUILDING A, HONGHUALING INDUSTRIAL PARK, NANSHAN DISTRICT",
                //    Tel= "18124649493",
                //    Post= "518052",
                //    Province = "GD",
                //    City= "Shenzhen",
                //    Country="CN"
                //};
            }


            var jSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };


            RestSharp.RestClient client = new RestSharp.RestClient(channel.ApiHost);
            RestSharp.RestRequest request = new RestSharp.RestRequest(action, RestSharp.Method.POST);
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(orderRequest, Formatting.Indented, jSetting);
            request.AddJsonBody(json);
            var res = client.Execute(request);
            if (res.StatusCode == System.Net.HttpStatusCode.OK)
            {
                OrderResult result = new OrderResult();
                try
                {
                    result = Newtonsoft.Json.JsonConvert.DeserializeObject<OrderResult>(res.Content);
                }
                catch (Exception ex)
                {
                    throw new Exception($"json解析错误{res.Content}");
                }
                if (result.statusCode == "success")
                {
                    var resultData = result.returnDatas[0];
                    if (resultData.statusCode == "success")
                    {
                        return new UploadResult
                        {
                            TrackingNumber = resultData.trackNumber,
                            ServiceOrderNumber = resultData.corpBillid,
                            IsSuccess = true
                        };
                    }
                    else
                    {
                        throw new Exception("服务商下单错误" + resultData.message);
                    }
                }
                else
                {
                    throw new Exception("服务商下单错误" + res.Content);
                }
            }
            else
            {
                throw new Exception($"服务商下单错误" + (res.ErrorMessage ?? res.Content));
            }


        }

        public async Task<byte[]> DrawPdfLabel(UploadResult result, Logistics_Channel channel, Order_Order order, List<Order_OrderGoods> orderGoods)
        {
            //channel.ApiKey = "0015";
            //channel.ApiSecret = "ZW55dWFu4SLizN78O8C0FH45qgbS";
            string action = "PostInterfaceService?method=printOrderLabel";
            RestSharp.RestClient client = new RestSharp.RestClient(channel.ApiHost);
            RestSharp.RestRequest request = new RestSharp.RestRequest(action, RestSharp.Method.POST);
            var obj = new
            {
                Verify = new
                {
                    Clientid = channel.ApiKey,
                    Token = channel.ApiSecret
                },
                CorpBillidDatas = new List<dynamic> { new { CorpBillid = result.ServiceOrderNumber }
                },
                OrderType = OrderType4.Contains(channel.Id) ? "4" : "1",//channel.PublicName == "MHD-Fedex-PAK" || channel.PublicName == "MHD-Fedex-PKG"
                PrintPaper = "label",
                PrintContent = "1",
            };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
            request.AddJsonBody(json);

            var response = client.Execute(request);
            if (response.StatusCode != System.Net.HttpStatusCode.OK)
                throw new Exception($"服务商下单错误" + (response.ErrorMessage ?? response.Content));

            try
            {
                var labelResult = Newtonsoft.Json.JsonConvert.DeserializeObject<LabelResult>(response.Content);
                if (labelResult.statusCode != "success")
                    throw new Exception($"服务商渠道获取面单路径失败{result.ServiceOrderNumber},{labelResult.message}");
                byte[] data = null;
                for (int i = 0; i < 5; i++)
                {
                    System.Net.WebClient webClient = new System.Net.WebClient();
                    data = webClient.DownloadData(labelResult.url);

                    if (data.Length > 5 * 1024)
                        return data;
                    //每三秒重试
                    System.Threading.Thread.Sleep(3 * 1000);
                }
                throw new Exception($"面单下载失败{labelResult.url}");
            }
            catch (Exception)
            {
                throw new Exception($"json解析错误{response.Content}");
            }

        }

        public Task<string> GetTrackingNumber(string SystemNo, string TrackingNumber, string ServiceOrderNo, Logistics_Channel channel)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// 打面单一样，这个打发票
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<byte[]> GetFP(Logistics_Channel channel, Order_Order order)
        {
            string action = "PostInterfaceService?method=printOrderLabel";
            RestSharp.RestClient client = new RestSharp.RestClient(channel.ApiHost);
            RestSharp.RestRequest request = new RestSharp.RestRequest(action, RestSharp.Method.POST);
            var obj = new
            {
                Verify = new
                {
                    Clientid = channel.ApiKey,
                    Token = channel.ApiSecret
                },
                CorpBillidDatas = new List<dynamic> { new { CorpBillid = order.ServicesOrderNo },
                },
                OrderType = "2",
                PrintPaper = "a4",
                PrintContent = "2",
            };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
            request.AddJsonBody(json);
            var response = client.Execute(request);
            if (response.StatusCode != System.Net.HttpStatusCode.OK)
                throw new Exception($"服务商发票获取异常" + (response.ErrorMessage ?? response.Content));
            try
            {
                var labelResult = Newtonsoft.Json.JsonConvert.DeserializeObject<LabelResult>(response.Content);
                if (labelResult.statusCode != "success")
                    throw new Exception($"服务商渠道获取面单路径失败{order.ServicesOrderNo},{labelResult.message}");

                byte[] data = null;
                for (int i = 0; i < 5; i++)
                {
                    System.Net.WebClient webClient = new System.Net.WebClient();
                    data = webClient.DownloadData(labelResult.url);

                    if (data.Length > 5 * 1024)
                        return data;
                    //每三秒重试
                    System.Threading.Thread.Sleep(3 * 1000);
                }
                throw new Exception($"面单下载失败{labelResult.url}");
            }
            catch (Exception ex)
            {
                throw new Exception($"json解析错误{response.Content}");
            }
        }
    }

}
