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

namespace XYY.Service.Standard.ChannelApi.HangLe
{
    public partial class Api : IBaseApi
    {
        public string ServiceName => "航乐";

        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 string[] ToArray(string str, int maxLength)
        //{
        //    string[] arr = str.Split(' ', '.');
        //    int page = ((str.Length + maxLength) - 1) / maxLength;
        //    string[] addressArr = new string[page];

        //    int flag = 0;
        //    int t = arr.Count();
        //    for (int i = 0; i < page; i++)
        //    {
        //        string temp = "";
        //        for (int j = 0; j < t; j++)
        //        {
        //            if ((temp += arr[flag] + " ").Length <= maxLength)
        //            {
        //                addressArr[i] += arr[flag] + " ";
        //                flag++;
        //            }
        //        }
        //        t = arr.Count() - flag;
        //    }
        //    return addressArr;
        //}
        public Task<UploadResult> DataUpload(Order_Order order, List<Order_OrderGoods> goods, Logistics_Channel channel, ExtendArg arg)
        {

            if (order.CustomerWeight > 4000)
                throw new Exception("渠道限重4KG");
            decimal rate = 1;
            if (goods.First()?.DeclareCurrency == "GBP")
                rate = 1.2489m;
            if (goods.Sum(x => x.DeclareFee * x.Quantity) > 15 * rate)
            {
                throw new Exception("渠道申报价值上限15GBP");
            }
            OrderReqeust orderReqeust = new OrderReqeust();
            orderReqeust.account = new Account
            {
                key = channel.ApiKey,
                password = channel.ApiSecret
            };
            var address = order.ReceiverStreet.ToArray(35);
            if (address.Length > 3)
                throw new Exception("收件人地址不能大于105位");

            System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"\w*?\d+\w*");
            if (!regex.IsMatch(order.ReceiverStreet))
            { 
                throw new Exception("收件人地址必须包含门牌号");
            }
            else
            {
                var groups = regex.Matches(order.ReceiverStreet);
                if (groups.Count > 0)
                {
                    string house = "";
                    if (groups.Count == 1)
                    {
                        house = groups[0].Value.Replace(" ", "");
                    }
                    else
                    {
                        for (int i = 0; i < groups.Count; i++)
                        {
                            house += groups[i].Value.Replace(" ", "");
                        }
                    }

                    if (house == order.ReceiverZipCode.Replace(" ", ""))
                    {
                        throw new Exception("收件人地址必须包含门牌号");
                    }
                }
            }

            orderReqeust.order = new Order()
            {
                country = order.ReceiverCountryCode,
                referenceCode = order.SystemNo,
                routeQuoteCode = channel.ServiceChannelCode,
                airportCode = String.Empty,
                consigneeInformation = new ConsigneeInformation
                {
                    consigneeName = order.ReceiverName,
                    consigneePhoneNumber = order.ReceiverPhone,
                    receivingCity = order.ReceiverCity,
                    receivingCountry = order.ReceiverCountryCode,
                    receivingPostalCode = order.ReceiverZipCode,
                    noticeEmail = order.ReceiverEmail,
                    receivingTown = order.ReceiverCity,
                    receivingAddress = address[0],
                    receivingAddress2 = address.Length > 1 ? address[1] : String.Empty,
                    receivingAddress3 = address.Length > 3 ? address[2] : String.Empty
                },
                box = new Box
                {
                    netWeight = (order.CustomerWeight / 1000.0).ToString(),
                    code = order.SystemNo,
                    commodities = goods.Select(x => new CommoditiesItem
                    {
                        code = x.GoodsNumber,
                        chineseName = x.CnName,
                        englishName = x.EnName,
                        customsCode = x.HsCode,
                        currency = x.DeclareCurrency,
                        price = x.DeclareFee.ToString(),
                        quantity = x.Quantity.ToString(),
                        whetherPowered = "2",
                        whetherWithMagnetic = "2"
                    }).ToList(),
                    remark = order.SystemNo
                }
            };

            RestSharp.RestClient client = new RestSharp.RestClient(channel.ApiHost);
            RestSharp.RestRequest request = new RestSharp.RestRequest("/app/json/otherOrder.action", RestSharp.Method.POST);
            request.AddJsonBody(orderReqeust);
            var response = client.Execute(request);
            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var result = Newtonsoft.Json.JsonConvert.DeserializeObject<OrderResult>(response.Content);

                if (result.content.ask == "Success")
                {
                    return Task.FromResult(new UploadResult
                    {
                        TrackingNumber = result.content.transferNumber,
                        IsSuccess = true,
                        ServiceOrderNumber = result.content.code,
                    });
                }
                else
                {
                    throw new Exception(string.Join(";",
                        result.content.errors.Select(x => x.message).ToArray()));
                }
            }
            else
            {
                throw new Exception(response.ErrorMessage ?? response.Content);
            }



        }//如果好用，请收藏地址，帮忙分享。
        public Task<byte[]> DrawPdfLabel(UploadResult result, Logistics_Channel channel, Order_Order order, List<Order_OrderGoods> orderGoods)
        {
            GetLabelRequest request = new GetLabelRequest();
            request.account = new Account();
            request.account.key = channel.ApiKey;
            request.account.password = channel.ApiSecret;
            request.order = new List<GetLabelRequest_Order> { new GetLabelRequest_Order { orderCode = result.ServiceOrderNumber } };
            RestSharp.IRestClient client = new RestSharp.RestClient(channel.ApiHost);
            RestSharp.IRestRequest restRequest = new RestSharp.RestRequest("/app/json/printLable.action", RestSharp.Method.POST);
            restRequest.AddJsonBody(request);
            int i = 0;
            do
            {
                try
                {
                    var response = client.Execute(restRequest);
                    if (response.StatusCode == System.Net.HttpStatusCode.OK)
                    {
                        var label = Newtonsoft.Json.JsonConvert.DeserializeObject<GetLabelResult>(response.Content);

                        if (label.content.ask == "Success")
                        {
                            return Task.FromResult(Convert.FromBase64String(label.content.printLable[0].imageStr));
                        }
                        else
                        {
                            throw new Exception($"获取面单失败{string.Join(";", label.content.errors, label.content.errors.Select(x => x.errorCode).ToArray())}");
                        }
                    }
                    else
                    {
                        throw new Exception($"获取面单失败{response.ErrorMessage ?? response.Content}");
                    }
                }
                catch (Exception ex)
                {
                    if (i < 3)
                    {
                        //3秒重试一次，最多重试3次
                        System.Threading.Thread.Sleep(3000);
                    }
                    else
                    {
                        throw ex;
                    }
                }
            } while (true);

        }

        public class GetLabelResult
        {
            public bool result
            {
                get; set;
            }
            public GetLabelResultContent content
            {
                get; set;
            }
        }

        public class GetLabelResultContent
        {
            public string ask
            {
                get; set;
            }

            public string message
            {
                get; set;
            }

            public List<ErrorsItem> errors
            {
                get; set;
            }

            public List<GetLabelResultContentItem> printLable
            {
                get; set;
            }
        }

        public class GetLabelResultContentItem
        {
            public string orderCode { get; set; }

            public string imageStr { get; set; }
        }

        public class GetLabelRequest
        {
            public Account account { get; set; }

            public List<GetLabelRequest_Order> order { get; set; }
        }

        public class GetLabelRequest_Order
        {
            public string orderCode
            {
                get; set;
            }
        }

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