using RestSharp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
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 XYY.Service.Standard.ChannelApi.GFSCronoApi.Model;

namespace XYY.Service.Standard.ChannelApi.GFSCronoApi
{
    public partial class Api : IBaseApi
    {
        #region 构造
        IOrder_OrderPrintQtyRepository _orderPrintQtyRepository;
        public Api(IOrder_OrderPrintQtyRepository orderPrintQtyRepository)
        {
            this._orderPrintQtyRepository =orderPrintQtyRepository;
        }
        #endregion
        #region 私有
        public string ServiceName => "GFSCrono";
        private string MapILErrMsg(string errCode)
        {
            switch (errCode)
            {
                case "50048": return "地址错误";
                default: return "未知错误代码";
            }
        }
        private CronoOrderRequest CreateOrderRequest(Logistics_Channel channel, Order_Order order, List<Order_OrderGoods> orderGoods, string channelOrderNumber)
        {
            List<LabelParameter> labelParameterALL = new List<LabelParameter>();
            var orderItem = CreateOrderParam(order, orderGoods, channel, channelOrderNumber);
            labelParameterALL.Add(orderItem);
            var requestBody = new CronoOrderRequest
            {
                ChannelNumber = channel.ServiceChannelCode,
                ChannelType = 1,
                UserName = channel.ApiKey,
                UserPWD = channel.ApiSecret,
                LabelParameterALL = labelParameterALL
            };

            return requestBody;
        }
        private LabelParameter CreateOrderParam(Order_Order order, List<Order_OrderGoods> orderGoods, Logistics_Channel channel, string channelOrderNumber)
        {
            List<DeclarationInfo> declarations = CreateDeclarationsParameter(order, orderGoods);
            OrdersModel ordersModel = CreateOrderInfoParam(order, channelOrderNumber);
            SendersModel sendersModel = CreateSenderInfo(channel);
            LabelParameter param = new LabelParameter
            {
                DeclarationsAll = declarations,
                OrdersModel = ordersModel,
                SendersModel = sendersModel,

            };
            return param;
        }
        private List<DeclarationInfo> CreateDeclarationsParameter(Order_Order order, List<Order_OrderGoods> orderGoods)
        {

            if (orderGoods?.Any() == true)
            {
                List<DeclarationInfo> param = new List<DeclarationInfo>();

                var orderWeight = order.OPWeight <= 0 ? order.CustomerWeight : order.OPWeight;
                var totalQty = orderGoods.Sum(g => g.Quantity);

                foreach (var g in orderGoods)
                {
                    var itemWeight = g.Weight;
                    if (itemWeight <= 0)
                    {
                        itemWeight = (orderWeight <= 0 ? 10 : orderWeight / totalQty);
                    }

                    DeclarationInfo item = new DeclarationInfo
                    {
                        Amount = Math.Round(g.DeclareFee, 2),
                        ChinaName = g.CnName,
                        EnglishName = g.EnName,
                        TotalAmount = Math.Round(g.DeclareFee * g.Quantity, 2),
                        Total = g.Quantity,
                        Weight = Math.Round(itemWeight / 1000m, 2),
                        Unit = "USD"
                    };
                    param.Add(item);
                }
                return param;
            }
            else
            {
                throw new Exception("物品信息不能为空");
            }

        }

        private OrdersModel CreateOrderInfoParam(Order_Order order, string channelOrderNumber)
        {

            var orderWeight = order.OPWeight > 0 ? order.OPWeight : (order.CustomerWeight > 0 ? order.CustomerWeight : 100);
            OrdersModel ordersModel = new OrdersModel
            {
                Address1 = order.ReceiverStreet,
                City = order.ReceiverCity,
                CompanyName = order.ReceiverCompany,
                DeclareType = 3,
                Email = order.ReceiverEmail,
                IsCod = order.IsCod ? 1 : 0,
                Mobile = order.ReceiverPhone,
                CodAmount = order.CodFee,
                Phone = order.ReceiverPhone,
                province = order.ReceiverState,
                ReceiveCountry = order.ReceiverCountryCode,
                Weight = orderWeight / 1000d,
                Total = 1,
                Zip = order.ReceiverZipCode.Trim(),
                Type = 2,
                ReceiveName = order.ReceiverName,
                CustomerCode = channelOrderNumber,

            };
            return ordersModel;
        }

        private SendersModel CreateSenderInfo(Logistics_Channel channel)
        {
            SendersModel sendersModel = new SendersModel
            {
                Adress = channel.SenderStreet,
                City = channel.SenderCity,
                CompanyName = channel.SenderCompany,
                Country = channel.SenderCountryCode,
                DoorNum = string.Empty,
                Email = channel.SenderEmail,
                Mobile = channel.SenderPhone,
                Province = channel.SenderState,
                SenderName = channel.SenderName,
                Zip = channel.SenderZipCode
            };
            return sendersModel;
        }
        private string GenerateSecondaryGainPDFByServiceCodeALL(UploadResult result, Logistics_Channel channel)
        {
            //如果小于70KB，直接调用二次生成接口
            string url = channel.ApiHost + "/LabelTemplate/GenerateSecondaryGainPDFByServiceCodeALL";
            RestClient restClient = new RestClient(url);
            var request = new RestRequest(Method.POST);
            request.AddJsonBody(new
            {
                ChannelNumber = channel.ServiceChannelCode,
                ServiceCodeALL = new string[] { result.TrackingNumber },
                UserName = channel.ApiKey,
                UserPWD = channel.ApiSecret
            });
            try
            {
                ///尝试二次获取面单，失败时，继续尝试
                var result2 = restClient.Execute(request);
                if (result2.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    GenerateSecondaryResult gr = Newtonsoft.Json.JsonConvert.DeserializeObject<GenerateSecondaryResult>(result2.Content);
                    return gr.PrintInfoALL[0].Url;
                }
                return string.Empty;
            }
            catch (Exception ex)
            {
                return string.Empty;
            }
        }
        #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)
        {
            var serviceOrderNum = $"{order.CustomerOrderNo}-{_orderPrintQtyRepository.GetPackagePrintQty(order.CustomerOrderNo)}";
            var requestParam = CreateOrderRequest(channel, order, goods, serviceOrderNum);
            RestClient client = new RestClient(channel.ApiHost);
            RestRequest req = new RestRequest("/usercenter/LabelTemplate/GetLabelALLAPI", Method.POST);
            req.Timeout = 10 * 1000;
            req.AddJsonBody(requestParam);
            DateTime from = DateTime.Now;
            var resp = client.Execute<GetLabelALLAPIResponse>(req);
            DateTime to = DateTime.Now;
            if (resp.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var respData = resp.Data;
                if (respData != null && string.IsNullOrWhiteSpace(respData.Error))
                {
                    if (respData.PrintInfoALL?.Any() != true)
                    {
                        //数据错误
                        throw new Exception("API返回结果异常");
                    }
                    else
                    {
                        var printInfo = respData.PrintInfoALL[0];
                        if (!string.IsNullOrWhiteSpace(printInfo.ErrCode) || !string.IsNullOrWhiteSpace(printInfo.Msg))
                        {
                            string errmsg = printInfo.Msg;

                            if (order.ReceiverCountryCode == "IL")
                            {
                                errmsg = MapILErrMsg(printInfo.ErrCode);
                            }

                            throw new Exception($"API返回异常:{errmsg} {printInfo.ErrCode}");
                        }
                        string trackingnumber = printInfo.Code;
                        UploadResult uploadResult = new UploadResult
                        {
                            ChannelId = channel.Id,
                            DownloadUrl = printInfo.Url,
                            ExecutionTime = (int)(to - from).TotalMilliseconds,
                            IsSuccess = true,
                            IsTransfer = false,
                            LazyDownloadLabel = false,
                            ResponseContent = resp.Content,
                            TrackingNumber = trackingnumber,
                            TransferNumner = order.TransferNumber,
                            ServiceOrderNumber = trackingnumber,

                        };
                        return uploadResult;
                    }
                }
                else
                {
                    string msg = null;
                    if (respData == null)
                    {
                        msg = $"API返回内容无效:{resp.Content}";
                    }
                    else
                    {
                        string detailMsg = null;
                        if (respData.PrintInfoALL?.Any() == true)
                        {
                            detailMsg = $"{respData.PrintInfoALL[0].Msg}({respData.PrintInfoALL[0].ErrCode})";
                        }
                        msg = $"{respData.Error} {detailMsg}";
                    }
                    //业务错误
                    UploadResult uploadResult = new UploadResult
                    {
                        IsSuccess = false,
                        Error = msg,
                        ExecutionTime = (int)(to - from).TotalMilliseconds,
                        ResponseContent = resp.Content,
                        ChannelId = channel.Id,
                    };
                    return uploadResult;
                }
            }
            else
            {
                //网络错误
                throw new Exception($"调用API失败:{resp.ErrorMessage}");
            }
        }

        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();
                if (channel.Id == 141)
                {
                    if (i == 0)
                    {
                        if (!string.IsNullOrEmpty(result.DownloadUrl))
                        {
                            data = client.DownloadData(result.DownloadUrl);
                        }
                    }
                    if (data != null && data.Length > 70 * 1024)
                    {
                        //意大利经济专线面单70K以上为正常面单
                        break;
                    }
                    else
                    {
                        string resultUrl = GenerateSecondaryGainPDFByServiceCodeALL(result, channel);
                        if (!string.IsNullOrEmpty(resultUrl))
                        {
                            result.DownloadUrl = resultUrl;
                            data = client.DownloadData(result.DownloadUrl);
                            if (data != null && data.Length > 70 * 1024)
                            {
                                //意大利经济专线面单70K以上为正常面单
                                break;
                            }
                        }
                    }
                }
                else
                {
                    if (data != null && data.Length > 5000)
                    {
                        break;
                    }
                    else
                    {
                        data = client.DownloadData(result.DownloadUrl);
                    }
                }
            }
            if ((data.Length > 70 * 1024 && channel.Id == 141) || (data.Length > 5000 && channel.Id != 141))
            {
                return data;
                //string pdfDir = Path.Combine(channel.LableDir, DateTime.Now.ToString_yyyyMMdd());
                //if (!Directory.Exists(pdfDir))
                //{
                //    Directory.CreateDirectory(pdfDir);
                //}
                //using (FileStream fs = new FileStream(Path.Combine(pdfDir, $"{result.TrackingNumber}.pdf"), FileMode.Create))
                //{
                //    fs.Write(data, 0, data.Length);
                //    fs.Flush();
                //}
                //return Path.Combine(pdfDir, $"{result.TrackingNumber}.pdf");
            }
            else
            {
                throw new Exception("面单下载失败");
            }
        }

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