using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XYY.Model.Standard.Channel;
using XYY.Model.Standard.Order;
using XYY.Service.Standard.ChannelApi.Base;
using XYY.Common.Standard;

namespace XYY.Service.Standard.ChannelApi.EcoFarmNatural
{
    public class Api : IBaseApi
    {
        private int retryGetLabelCodeCount = 3;
        private int retryDownLabelCount = 3;

        public string ServiceName => "EcoFarmNatural";

        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)
        {
            //http://nz.ecofarmnatural.com/interface/ship/create_lable.htm
            string host = channel.ApiHost;
            RestClient client = new RestClient(host);
            RestRequest request = new RestRequest("/interface/ship/create_lable.htm");
            request.Method = Method.POST;
            request.AddHeader("Content-Type", "application/x-www-form-urlencoded");

            SetParameters(request, channel, order, goods);


            var response = await client.ExecuteAsync<ResponseWrap<ReponseBase>>(request);
            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var content = response.Content;
                if (string.IsNullOrWhiteSpace(content))
                {
                    throw new Exception("下单api返回内容为空");
                }

                ResponseWrap<ReponseBase> data = response.Data;

                if (data.data.state == "success")
                {
                    string trackingNumber = await GetLabelCode(channel, order.TransferNumber);
                    if (string.IsNullOrWhiteSpace(trackingNumber))
                    {
                        string msg = $"已重试{retryGetLabelCodeCount}次仍不能获取跟踪号";
                        throw new Exception($"下单出错 {msg}");
                    }
                    else
                    {
                        var uploadResult = new UploadResult
                        {
                            IsSuccess = true,
                            ServiceOrderNumber = trackingNumber,
                            TrackingNumber = trackingNumber
                        };
                        return uploadResult;
                    }
                }
                else
                {
                    string msg = string.IsNullOrWhiteSpace(data.data.message) ? content : data.data.message;
                    throw new Exception($"下单API提示错误 {msg}");
                }

            }
            else
            {
                string msg = string.IsNullOrWhiteSpace(response.ErrorMessage) ? response.Content : response.ErrorMessage;
                throw new Exception($"下单API提示错误 {msg}");
            }
        }


        private void SetParameters(RestRequest request, Logistics_Channel channel, Order_Order order, List<Order_OrderGoods> goods)
        {
            int orderWeight = order.OPWeight <= 0 ? order.CustomerWeight : order.OPWeight;
            decimal orderWeightKg = orderWeight / 1000m;

            string street = order.ReceiverStreet;
            //string[] addresses = street.ToArray(35);
            //if (addresses.Length > 2)
            //    throw new Exception("地址超长");
            //string address1 = addresses[0];
            //string address2 = addresses.Length > 1 ? addresses[1] : null;



            List<OrderDetails> orderDetails = GetOrderDetail(goods);
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(orderDetails);

            request.AddParameter("consigneeAddr1", street, ParameterType.GetOrPost);
            request.AddParameter("consigneeAddr2", order.ReceiverCity, ParameterType.GetOrPost);
            request.AddParameter("consigneeBuilding", null, ParameterType.GetOrPost);
            request.AddParameter("consigneeCity", order.ReceiverCity, ParameterType.GetOrPost);
            request.AddParameter("consigneeCompany", order.ReceiverCompany, ParameterType.GetOrPost);
            request.AddParameter("consigneeCountry", order.ReceiverCountryCode, ParameterType.GetOrPost);
            request.AddParameter("consigneeEmail", order.ReceiverEmail, ParameterType.GetOrPost);
            request.AddParameter("consigneeName", order.ReceiverName, ParameterType.GetOrPost);
            request.AddParameter("consigneePhone", order.ReceiverPhone, ParameterType.GetOrPost);
            request.AddParameter("consigneePostCode", order.ReceiverZipCode, ParameterType.GetOrPost);
            request.AddParameter("consignor", "GaoZhuo", ParameterType.GetOrPost);
            request.AddParameter("consignorAddr1", "Block A Floor 5, shixia road 8", ParameterType.GetOrPost);
            request.AddParameter("consignorAddr2", "GuangZhou", ParameterType.GetOrPost);
            request.AddParameter("consignorPhone", "18588532219", ParameterType.GetOrPost);
            request.AddParameter("consignorPostCode", "510000", ParameterType.GetOrPost);
            request.AddParameter("ddpDdu", "DDU", ParameterType.GetOrPost);
            request.AddParameter("destination", "NZAKL", ParameterType.GetOrPost);
            request.AddParameter("overNight", "N", ParameterType.GetOrPost);
            request.AddParameter("packageHeight", 1, ParameterType.GetOrPost);
            request.AddParameter("packageLength", 1, ParameterType.GetOrPost);
            request.AddParameter("packagesType", "PK", ParameterType.GetOrPost);
            request.AddParameter("packageWidth", 1, ParameterType.GetOrPost);
            request.AddParameter("privateKey", channel.ApiSecret, ParameterType.GetOrPost);
            request.AddParameter("referenceNum", order.TransferNumber, ParameterType.GetOrPost);
            request.AddParameter("signatureRequired", false, ParameterType.GetOrPost);
            request.AddParameter("totalWeight", orderWeightKg, ParameterType.GetOrPost);
            request.AddParameter("orderDetails", json, ParameterType.GetOrPost);
        }




        private List<OrderDetails> GetOrderDetail(List<Order_OrderGoods> goods)
        {
            List<OrderDetails> result = new List<OrderDetails>();
            int idx = 1;

            foreach (var g in goods)
            {
                decimal kg = Math.Round(g.Weight / 1000m, 2);
                OrderDetails d = new OrderDetails
                {
                    cityOrigin = "CN",
                    currency = "NZD",
                    detailGoods = g.EnName,
                    num = g.Quantity,
                    priceUnit = g.DeclareFee,
                    serialNo = idx++,
                    weightKg = kg
                };
                result.Add(d);
            }

            return result;
        }

        private async Task<string> GetLabelCode(Logistics_Channel channel, string transferNumber)
        {
            //GetLabelCodeRequest param = new GetLabelCodeRequest { privateKey = channel.ApiSecret, referenceNum = transferNumber };
            RestClient client = new RestClient(channel.ApiHost);
            RestRequest request = new RestRequest("/interface/ship/get_lable_code.htm", Method.POST);
            //request.AddJsonBody(param);
            request.AddParameter("privateKey", channel.ApiSecret, ParameterType.GetOrPost);
            request.AddParameter("referenceNum", transferNumber, ParameterType.GetOrPost);

            for (int i = 0; i < retryGetLabelCodeCount; i++)
            {
                var response = await client.ExecuteAsync<ResponseWrap<DownLabelCodeResponse>>(request);

                if (response.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    if (response.Data?.data != null && response.Data.data.state == "success")
                    {
                        return response.Data.data.labelCode;
                    }
                    else if (response.Data?.data == null || response.Data.data.message.Contains("订单的面单号尚未生成"))
                    {
                        System.Threading.Thread.Sleep(1000);
                        continue;
                    }
                }
                else
                {
                    throw new Exception($"下载面单API调用失败:{response.Content}");
                }
            }
            return null;
        }

        public async Task<byte[]> DrawPdfLabel(UploadResult result, Logistics_Channel channel, Order_Order order, List<Order_OrderGoods> orderGoods)
        {
            //DownLabelRequestParam param = new DownLabelRequestParam { privateKey = channel.ApiSecret, labelCode = order.TransferNumber };
            string host = channel.ApiHost;
            RestClient client = new RestClient(host);
            RestRequest request = new RestRequest("/interface/ship/download_lable.htm", Method.POST);
            //request.AddJsonBody(request);
            request.AddParameter("privateKey", channel.ApiSecret, ParameterType.GetOrPost);
            request.AddParameter("labelCode", result.TrackingNumber, ParameterType.GetOrPost);

            for (int i = 0; i < retryDownLabelCount; i++)
            {
                var response = await client.ExecuteAsync<ResponseWrap<DownLabelReponse>>(request);

                if (response.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    DownLabelReponse data = response.Data?.data;
                    if (data == null)
                    {
                        string msg = $"获取面单API返回响应无效:{response.Content}";
                        throw new Exception(msg);
                    }
                    if (data.state == "success")
                    {
                        string base64 = response.Data.data.lableFile;
                        var pdf = Convert.FromBase64String(base64);
                        return pdf;
                    }
                    else
                    {
                        System.Threading.Thread.Sleep(1000);
                    }
                }
                else
                {
                    throw new Exception("面单下载API异常 " + response.ErrorMessage ?? response.Content);
                }
            }
            throw new Exception($"面单下载失败(已重试{retryDownLabelCount}次)");
        }

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