using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XYY.Core.Standard.FiddlerClient;
using XYY.Data.Standard.Order;
using XYY.Model.Standard.Channel;
using XYY.Model.Standard.Order;
using XYY.Service.Standard.ChannelApi.Base;
using XYY.Service.Standard.ChannelApi.G3SpringAPI.Model;

namespace XYY.Service.Standard.ChannelApi.G3SpringAPI
{
    public partial class Api : IBaseApi
    {
        #region 构造
        IOrder_OrderPrintQtyRepository _order_OrderPrintQtyRepository;
        public Api(IOrder_OrderPrintQtyRepository order_OrderPrintQtyRepository)
        {
            this._order_OrderPrintQtyRepository = order_OrderPrintQtyRepository;
        }
        #endregion
        #region 私有
        public string ServiceName => "G3Spring";
        ///api账号的账号信息,item1=channelId,item2=customerId,item3=customerCode
        private List<Tuple<int, string, string>> apiCustomerInfos = new List<Tuple<int, string, string>>
            {
                new Tuple<int, string, string>(138,"HK XINGYUNYI","H-107280"),
                new Tuple<int, string, string>(160,"广州行运易国际货运代理有限公司","GZXYYGJHY"),

            };
        private void GoodsJudge(List<Order_OrderGoods> goods,Order_Order order)
        {
            Dictionary<string, string> goodsNames = new Dictionary<string, string>();
            goodsNames.Add("裤子", "trousers");
            goodsNames.Add("首饰", "jewelry");
            goodsNames.Add("耳环", "earring");
            goodsNames.Add("衬衫", "Shirts");
            goodsNames.Add("项链", "necklace");
            goodsNames.Add("鞋子", "casual shoes");
            goodsNames.Add("袜子", "stocking");
            goodsNames.Add("包包", "handbag");
            goodsNames.Add("手链", "Bracelets");
            goodsNames.Add("腰带", "waistband");
            goodsNames.Add("内衣", "underwear");
            goodsNames.Add("围巾", "Muffler");
            goodsNames.Add("外衣", "Outerwear");
            goodsNames.Add("毛衣", "Sweater");
            goodsNames.Add("手套", "gloves");
            goodsNames.Add("套装", "casual outfit");
            goodsNames.Add("靴子", "Casual boots");
            foreach (var item in goods)
            {
                if (goodsNames.ContainsKey(item.CnName))
                {
                    item.EnName = goodsNames[item.CnName];
                }
            }

            if (order.ChannelId == 160)
            {
                var originOrderGoods = goods;
                goods = goods.CopyList<Order_OrderGoods>().ToList();
                //SetOPGoodsValues(order, orderGoods, originOrderGoods, 500, 90, 99);
            }
        }
        private ConsigneeData CreateConsigneeData(Order_Order order)
        {
            ConsigneeData data = new ConsigneeData
            {
                buyer_id = string.Empty,
                consignee_certificatecode = string.Empty,
                consignee_certificatetype = string.Empty,
                consignee_city = order.ReceiverCity,
                consignee_company = order.ReceiverCompany,
                consignee_credentials_period = string.Empty,
                consignee_doorplate = string.Empty,
                consignee_email = order.ReceiverEmail,
                consignee_mobile = order.ReceiverPhone,
                consignee_name = order.ReceiverName,
                consignee_postcode = order.ReceiverZipCode,
                consignee_province = order.ReceiverState,
                consignee_street = order.ReceiverStreet,
                consignee_street2 = null,
                consignee_street3 = null,
                consignee_taxno = order.TaxNo,
                consignee_telephone = order.ReceiverPhone
            };
            return data;
        }
        private ShipperData CreateShipper(Logistics_Channel channel)
        {
            ShipperData data = new ShipperData
            {
                order_note = string.Empty,
                shipper_areacode = string.Empty,
                shipper_city = channel.SenderCity,
                shipper_company = channel.SenderCompany,
                shipper_countrycode = channel.SenderCountryCode,
                shipper_email = channel.SenderEmail,
                shipper_fax = string.Empty,
                shipper_mobile = string.Empty,
                shipper_name = channel.SenderName,
                shipper_postcode = channel.SenderZipCode,
                shipper_province = channel.SenderState,
                shipper_street = channel.SenderStreet,
                shipper_telephone = channel.SenderPhone
            };
            return data;
        }
        private List<ItemArr> CreateItems(Order_Order order, List<Order_OrderGoods> orderGoods)
        {
            List<ItemArr> list = new List<ItemArr>();

            foreach (var i in orderGoods)
            {
                var itemWeight = i.Weight;
                if (itemWeight <= 0)
                {
                    var orderWeight = order.OPWeight <= 0 ? order.CustomerWeight : order.OPWeight;
                    var totalQty = orderGoods.Sum(g => g.Quantity);
                    totalQty = totalQty == 0 ? 1 : totalQty;
                    itemWeight = orderWeight / totalQty;
                }

                ItemArr item = new ItemArr
                {
                    hs_code = i.HsCode,
                    invoice_cnname = i.CnName,
                    invoice_currencycode = i.DeclareCurrency,
                    invoice_enname = i.EnName,
                    invoice_weight = (float)Math.Round(itemWeight / 1000f, 3),
                    invoice_quantity = i.Quantity,
                    invoice_unitcharge = (float)i.DeclareFee,
                    sku = i.GoodsNumber,
                    invoice_note = "",
                    invoice_url = "",
                    unit_code = ""
                };
                list.Add(item);
            }
            return list;
        }
        private T CallService<T>(Logistics_Channel channel, object param, string serviceName, out string paramJson, out string responseJson) where T : class, new()
        {
            var apiCustomerInfo = apiCustomerInfos.FirstOrDefault(i => i.Item1 == channel.Id);
            if (apiCustomerInfo == null)
                throw new Exception("缺少账号客户代码信息");

            string token = channel.ApiKey;
            string appKey = channel.ApiSecret;
            string customerId = apiCustomerInfo.Item2;
            string customerCode = apiCustomerInfo.Item3;
            string transformation = null;
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(param);
            SprintAPI.EcClient ecClient = new SprintAPI.EcClient(SprintAPI.EcClient.EndpointConfiguration.EcSOAP, channel.ApiHost);
            //代理设置
            var b = ecClient.Endpoint.Binding as System.ServiceModel.BasicHttpBinding;
            FiddlerClient.SetProxy(b);

            string resp = ecClient.callServiceAsync(json, token, appKey, customerId, customerCode, transformation, serviceName).Result.Body.response;
            paramJson = json;
            try
            {
                T result = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(resp);
                responseJson = resp;
                return result;
            }
            catch (Exception ex)
            {
                throw new Exception($"解析响应结果失败:{ex.Message},Content:{resp}");
            }
        }
        private void CheckError(string operationName, WSResponseBase responseData)
        {
            if (responseData.ask == "Failure")
            {
                string err = responseData.message;
                string detail = responseData.Error?.errMessage;
                string code = responseData.Error?.errCode;
                string msg = $"{operationName}出错,{err}:{detail},代码:{code}";
                throw new Exception(msg);
            }
        }
        private string GetLabel(string referenceNo, Logistics_Channel channel)
        {
            GetLabelParam param = new GetLabelParam
            {
                reference_no = referenceNo
            };
            var resp = CallService<LabelResponseData>(channel, param, "getLabelUrl", out string json, out string respJson);
            CheckError("获取面单", resp);
            return resp.url;
        }
        #endregion 私有
        #region 实现接口

        public Task<List<BagDeclareErrosResult>> BagDeclare(BagDeclareRequest bagDeclareRequest)
        {
            throw new NotImplementedException();
        }

        public void CannelOrders(List<string> systemNO)
        {
            throw new NotImplementedException();
        }
        public void CannelOrdersByModel(logistics_ChannelCancel model)
        {
            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)
        {
            GoodsJudge(goods,order);
            DateTime from = DateTime.Now;
            string referenceNo = order.SystemNo;// order.CustomerOrderNo + "-" + _order_OrderPrintQtyRepository.GetPackagePrintQty(order.CustomerOrderNo);// order.SystemNo;
            ConsigneeData consignee = CreateConsigneeData(order);
            ShipperData shipper = CreateShipper(channel);
            List<ItemArr> itemArr = CreateItems(order, goods);

            var orderWeight = order.OPWeight <= 0 ? order.CustomerWeight : order.OPWeight;
            CreateOrderData param = new CreateOrderData
            {
                Consignee = consignee,
                Shipper = shipper,
                ItemArr = itemArr,
                reference_no = referenceNo,
                shipper_hawbcode = string.Empty,
                country_code = order.ReceiverCountryCode,
                order_weight = orderWeight / 1000f,
                shipping_method_no = string.Empty,
                shipping_method = channel.ServiceChannelCode,
            };
            var j = Newtonsoft.Json.JsonConvert.SerializeObject(param);
            var responseData = CallService<WSResponseData>(channel, param, "createOrder", out string json, out string respJson);

            CheckError("下单", responseData);

            string labelUrl = GetLabel(referenceNo, channel);
            DateTime end = DateTime.Now;
            int executionTime = (int)(end - from).TotalMilliseconds;
            UploadResult result = new UploadResult
            {
                ChannelId = channel.Id,
                DownloadUrl = labelUrl,
                destinationCode = string.Empty,
                Error = string.Empty,
                IsSuccess = true,
                IsTransfer = false,
                ExecutionTime = executionTime,
                LabelData = null,
                LazyDownloadLabel = false,
                OrderGoodsJosn = string.Empty,
                OrderJosn = json,
                ResponseContent = respJson,
                TrackingNumber = responseData.shipping_method_no,
                TransferNumner = order.SystemNo,
                ServierFee = 0,
                ServiceOrderNumber = string.Empty,
                ServiceOrderNumber2 = string.Empty,
                ServiceOrderNumber3 = string.Empty
            };
            return result;
        }

        public async Task<byte[]> DrawPdfLabel(UploadResult result, Logistics_Channel channel, Order_Order order, List<Order_OrderGoods> orderGoods)
        {
            byte[] data = null;
            for (int i = 0; i < 3; i++)
            {

                System.Net.WebClient client = new System.Net.WebClient();
                try
                {
                    data = client.DownloadData(result.DownloadUrl);
                }
                catch (Exception ex)
                {
                }
                if (data != null && data.Length > 5000)
                {
                    break;
                }
                else
                {
                    //超过10KB为有效文件，否则线程等待2s
                    System.Threading.Thread.Sleep(4000);
                }
            }
            if (data.Length > 5000)
            {
                return data;
            }
            else
            {
                throw new Exception("面单下载失败，请稍候重试," + result.DownloadUrl);
            }
        }

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