using Microsoft.Extensions.Logging;
using Nest;
using Newtonsoft.Json;
using NPOI.HSSF.Record.Chart;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XYY.Core.Standard.PDF;
using XYY.Model.Standard.Channel;
using XYY.Model.Standard.Order;
using XYY.Service.Standard.ChannelApi._4PX;
using XYY.Service.Standard.ChannelApi.Base;
using XYY.Service.Standard.ChannelApi.HuoYing;
using XYY.Service.Standard.ChannelApi.SSD_USPS;
using static XYY.Service.Standard.ChannelApi._4PX.Api;

namespace XYY.Service.Standard.ChannelApi.DeLiXun
{
    public partial class Api : IBaseApi
    {
        public string ServiceName => "dlxfedex";
        ILogger<Api> _logger;
        public Api(ILogger<Api> logger)
        {
            _logger = logger;
        }

        public Task<List<Base.BagDeclareErrosResult>> BagDeclare(Model.Standard.Order.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 post = await ConvertOrder(order, goods, channel, arg);
            string json = JsonConvert.SerializeObject(post);
            RestClient client = new RestClient(channel.ApiHost + "/createOrderApi.htm");
            RestRequest request = new RestRequest(Method.POST);
            request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
            request.AddParameter("param", json);
            var response = client.Execute(request);
            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var result = JsonConvert.DeserializeObject<DataUploadResult>(response.Content);
                result.message = System.Web.HttpUtility.UrlDecode(result.message, Encoding.UTF8);
                if (result.ack == "true")
                {
                    _logger.LogError("德立迅下单成功:{@Response}", result);
                    var uploadResult = new UploadResult
                    {
                        IsSuccess = true,
                        MPSTrackings = new Dictionary<string, string>(),
                        TrackingNumber = result.tracking_number,
                        ServiceOrderNumber = result.order_id,
                    };
                    return uploadResult;
                }
                else
                {
                    throw new Exception($"德立迅下单失败:{result.message}");
                }
            }
            else
            {
                throw new Exception($"德立迅下单失败:{response.Content ?? response.ErrorMessage}");
            }
        }

        public async Task<byte[]> DrawPdfLabel(Base.UploadResult result, Model.Standard.Channel.Logistics_Channel channel, Model.Standard.Order.Order_Order order, List<Order_OrderGoods> orderGoods)
        {
            string pdfURL = channel.ServiceTrackingUrl + "/order/FastRpt/PDF_NEW.aspx?PrintType=lab10_10&Format=" + "&order_id=" + result.ServiceOrderNumber;

            if (string.IsNullOrEmpty((result.TrackingNumber)))
            {
                throw new Exception("返回的运单号有问题");
            }

            byte[] data = null;
            System.Net.WebClient client = new System.Net.WebClient();
            for (int i = 0; i < 3; i++)
            {
                data = await client.DownloadDataTaskAsync(new Uri(pdfURL));
                if (data.Length > 1 * 1024)
                {
                    //面单大于5k时返回
                    break;
                }
                //3秒后重试一次
                System.Threading.Thread.Sleep(3 * 1000);
            }
            if (data == null || data.Length < 1 * 1024)
            {
                throw new Exception("面单获取失败，请稍候重试");
            }
            return data;
        }

        public async Task<string> GetTrackingNumber(string SystemNo, string TrackingNumber, string ServiceOrderNo, Logistics_Channel channel)
        {
            var client = new RestClient($"{channel.ApiHost}/getOrderTrackingNumber.htm?documentCode={SystemNo}");
            client.Timeout = -1;
            var request = new RestRequest(Method.GET);
            IRestResponse response = client.Execute(request);
            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var data = JsonConvert.DeserializeObject<GetOrderTrackingNumberResult>(response.Content);
                if (data.order_serveinvoicecode.Contains("KD")) { throw new Exception($"德立迅获取末端单号不正确:{data.order_serveinvoicecode}，仍是KD单号。"); }
                return data.order_serveinvoicecode;
            }
            else {
                throw new Exception($"德立迅获取末端单号失败:{response.Content ?? response.ErrorMessage}");
            }
        }
        private async Task<DataUploadRequest> ConvertOrder(Order_Order order, List<Order_OrderGoods> goods, Logistics_Channel channel, ExtendArg arg)
        {
            if (order.ReceiverStreet.Length > 35) { throw new Exception("德立迅API限制地址长度为35位，当前地址长度已超出限制！"); }
            DataUploadRequest post = new DataUploadRequest();
            post.consignee_mobile = order.ReceiverPhone;
            post.trade_type = "ZYXT";
            post.duty_type = " DDU";
            post.consignee_name = order.ReceiverName;
            post.consignee_companyname = order.ReceiverCompany;
            post.consignee_address = order.ReceiverStreet;
            post.consignee_telephone = order.ReceiverPhone;
            post.country = order.ReceiverCountryCode;
            post.consignee_state = order.ReceiverState;
            post.consignee_city = order.ReceiverCity;
            post.consignee_postcode = order.ReceiverZipCode;
            post.consignee_email = order.ReceiverEmail;
            post.order_customerinvoicecode = order.SystemNo;
            post.weight = (order.CustomerWeight / 1000.0m).ToString();
            post.cargo_type = channel.PublicName.Contains("PKG") ? "P" : "B";

            post.customer_id = channel.ApiKey.Split(";")[1];
            post.customer_userid = channel.ApiKey.Split(";")[2];
            post.product_id = channel.ServiceChannelCode;
            post.orderInvoiceParam = new List<OrderInvoiceParamItem>();
            post.orderVolumeParam = new List<OrderVolumeParamItem>() {
                new OrderVolumeParamItem() {volume_weight= (order.CustomerWeight / 1000.0m).ToString(), }
            };
            foreach (var item in goods)
            {
                var tempData = new OrderInvoiceParamItem()
                {
                    invoice_amount = item.DeclareFee.ToString(),
                    invoice_pcs = "1",
                    invoice_title = item.EnName,
                    invoice_weight = (item.Weight / 1000.0m).ToString(),
                    sku = item.CnName,
                    hs_code = item.HsCode,
                    invoiceunit_code = "件",
                    invoice_currency = item.DeclareCurrency,
                    invoice_material = item.Remark,
                    invoice_purpose = "Housewear",
                };
                post.orderInvoiceParam.Add(tempData);
            }

            return post;
        }
    }
}
