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.MpsOrder;
using XYY.Model.Standard.Order;
using XYY.Service.Standard.ChannelApi.Base;

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

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


        public async Task<T2> Send<T1, T2>(T1 data, Logistics_Channel channel, string action)
        {
            RestSharp.RestClient client = new RestSharp.RestClient(channel.ApiHost);
            RestSharp.RestRequest request = new RestSharp.RestRequest(action, RestSharp.Method.POST, RestSharp.DataFormat.Json);
            request.AddJsonBody(data);
            request.AddHeader("Authorization", channel.ApiKey + ";" + channel.ApiSecret);
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
            var resposne = client.Execute(request);
            if (resposne.StatusCode == System.Net.HttpStatusCode.OK)
            {
                try
                {
                    return Newtonsoft.Json.JsonConvert.DeserializeObject<T2>(resposne.Content);
                }
                catch (Exception ex)
                {
                    throw new Exception("Json返回结果解析失败" + ex.Message);
                }
            }
            else
            {
                throw new Exception(resposne.Content ?? resposne.ErrorMessage);
            }

        }

        public OrderRquest ConvertRequest(Order_Order order, List<Order_OrderGoods> goods, Logistics_Channel channel, Order_MpsOrder mpsOrder)
        {
            if (!string.IsNullOrEmpty(order.CustomerOrderNo))
            {
                if (order.CustomerOrderNo.Split('_').Length > 2)
                {
                    //多杰仅保留前两个客单号
                    order.CustomerOrderNo = string.Join('_', order.CustomerOrderNo.Split('_').Take(2));
                }
                order.CustomerOrderNo = order.CustomerOrderNo.Replace("/","_");
            }
            //DY 服务地址为4位FBA仓库代码
            if(channel.Id == 472)
            {
                System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"[A-Z]{3}\d{1}");
                if (!regex.IsMatch(order.ReceiverName))
                    throw new Exception("DY产品收件人应为FBA仓库代码");
            }
            if (channel.Id == 406 || channel.Id == 460 || channel.Id == 487 || channel.Id == 488)
            {

                Dictionary<string, string> pairs = new Dictionary<string, string>
                {
                    { "Washington", "WA" },
                    { "Oregon", "OR" },
                    { "California", "CA" },
                    { "Nevada", "NV" },
                    { "Idaho", "ID" },
                    { "Utah", "UT" },
                    { "Arizona", "AZ" },
                    { "Montana", "MT" },
                    { "Wyoming", "WY" },
                    { "Colorado", "CO" },
                    { "New Mexico", "NM" },
                    { "Wisconsin", "WI" },
                    { "Illinois", "IL" },
                    { "Tennessee", "TN" },
                    { "Mississippi", "MS" },
                    { "Michigan", "MI" },
                    { "Indiana", "IN" },
                    { "Kentucky", "KY" },
                    { "Alabama", "AL" },
                    { "Ohio", "OH" },
                    { "West Virginia", "WV" },
                    { "Virginia", "VA" },
                    { "North Carolina", "NC" },
                    { "South Carolina", "SC" },
                    { "Georgia", "GA" },
                    { "North Dakota", "ND" },
                    { "South Dakota", "SD" },
                    { "Nebraska", "NE" },
                    { "Kansas", "KS" },
                    { "Oklahoma", "OK" },
                    { "Texas", "TX" },
                    { "Minnesota", "MN" },
                    { "Iowa", "IA" },
                    { "Missouri", "MO" },
                    { "Arkansas", "AR" },
                    { "Louisiana", "LA" },
                    { "Florida", "FL" },
                    { "Pennsylvania", "PA" },
                    { "New York", "NY" },
                    { "Washington D. C.", "DC" },
                    { "Maryland", "MD" },
                    { "Delaware", "DE" },
                    { "New Jersey", "NJ" },
                    { "Connecticut", "CT" },
                    { "Rhode Island", "RI" },
                    { "Massachusetts", "MA" },
                    { "Maine", "ME" },
                    { "New Hampshire", "NH" },
                    { "Vermont", "VT" }
                };

                if (!pairs.Keys.Any(x => x.Equals(order.ReceiverState, StringComparison.CurrentCultureIgnoreCase))
                        && !pairs.Values.Any(x => x.Equals(order.ReceiverState, StringComparison.CurrentCultureIgnoreCase))
                        )
                {
                    if (pairs.Keys.Any(x => x.Equals(order.ReceiverCity, StringComparison.CurrentCultureIgnoreCase)))
                    {
                        string state = order.ReceiverState;
                        order.ReceiverState = pairs.Where(x => x.Key.Equals(order.ReceiverCity, StringComparison.CurrentCultureIgnoreCase)).First().Value;
                        order.ReceiverCity = state;
                    }
                    else if (pairs.Values.Any(x => x.Equals(order.ReceiverCity, StringComparison.CurrentCultureIgnoreCase)))
                    {
                        string state = order.ReceiverState;
                        order.ReceiverState = order.ReceiverCity;
                        order.ReceiverCity = order.ReceiverState;
                    }
                    else
                    {
                        throw new Exception("美国专线必须传入标准的州名或州简写");
                    }
                }
                else if (pairs.Keys.Any(x => x.Equals(order.ReceiverState, StringComparison.CurrentCultureIgnoreCase)))
                {
                    order.ReceiverState = pairs.Where(x => x.Key.Equals(order.ReceiverState, StringComparison.CurrentCultureIgnoreCase)).First().Value;
                }
                System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"\+1 \d{3}-\d{3}-\d{4} ext. \d{5}");
                if (regex.IsMatch(order.ReceiverPhone))
                {
                    order.ReceiverPhone
                        = order.ReceiverPhone.Replace("+1", "").Replace("-", "").Replace(" ext. ", "").Trim();
                }
            }
            OrderRquest orderRquest = new OrderRquest();
            orderRquest.shipper = new Shipper
            {
                address = channel.SenderStreet,
                city = channel.SenderCity,
                companyName = channel.SenderCompany,
                countryCode = channel.SenderCountryCode,
                name = channel.SenderName,
                phone = channel.SenderPhone,
                postcode = channel.SenderZipCode,
                stateProvince = channel.SenderState
            };
            orderRquest.consignee = new Consignee
            {
                name = order.ReceiverName,
                companyName = order.ReceiverName,
                countryCode = order.ReceiverCountryCode,
                stateProvince = order.ReceiverState,
                address = order.ReceiverStreet,
                postcode = order.ReceiverZipCode,
                phone = order.ReceiverPhone,
                city = order.ReceiverCity
            };
            orderRquest.boxes = mpsOrder.Boxs.Select(x =>
            {
                return new BoxesItem
                {
                    code = x.BoxNumber,
                    weight = x.OpInputWeight,
                    width = x.OpWidth,
                    height = x.OpHeight,
                    length = x.OpLength,
                    declareProducts = x.Goods.Select(x => new DeclareProductsItem
                    {
                        declareNameCn = x.CnName,
                        declareNameEn = x.EnName,
                        hsCode = x.HsCode,
                        declareNote = x.Brand + ";" + x.Meterial,
                        declareValue = x.GoodsValue,
                        quantity = x.Quantity,
                        url = x.SaleLink
                    }).ToList()
                };
            }).ToList();

            orderRquest.orderNo = order.CustomerOrderNo;
            orderRquest.productCode = channel.ServiceChannelCode;
            orderRquest.labelType = "onePdf";
            return orderRquest;
        }

        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)
        {
            //await SS(order, goods, channel, arg);
            var orderRequest = ConvertRequest(order, goods, channel, arg.Order);
            var result = await Send<OrderRquest, OrderResult>(orderRequest, channel, "label");
            if (result.success)
            {
                var uploadResult = new UploadResult
                {
                    DownloadUrl = result.labelFileBody,
                    IsSuccess = true,
                    MPSTrackings = new Dictionary<string, string>(),
                    TrackingNumber = result.trackingNumber
                };
                for (int i = 0; i < result.boxes.Count; i++)
                {
                    uploadResult.MPSTrackings.Add(arg.Order.Boxs[i].BoxServiceNumber, result.boxes[i].trackingNumber);
                }
                return uploadResult;
            }
            else
            {
                //如果已存在
                if (result.message.Contains("订单号重复"))
                {
                    string url = "http://api.dorje56.com/order?cmCode=" + channel.ApiKey + "&token=" + channel.ApiSecret + "&orderNumber=" + orderRequest.orderNo;
                    url += "&labelType=onePdf";
                    var strOrderInfoResult = new System.Net.WebClient().DownloadString(url);
                    if (!string.IsNullOrEmpty(strOrderInfoResult))
                    {
                        var orderInfoResult = Newtonsoft.Json.JsonConvert.DeserializeObject<OrderResult>(strOrderInfoResult);
                        var uploadResult = new UploadResult
                        {
                            DownloadUrl = orderInfoResult.labelFileBody,
                            IsSuccess = true,
                            MPSTrackings = new Dictionary<string, string>(),
                            TrackingNumber = orderInfoResult.trackingNumber
                        };
                        for (int i = 0; i < orderInfoResult.boxes.Count; i++)
                        {
                            uploadResult.MPSTrackings.Add(arg.Order.Boxs[i].BoxServiceNumber, orderInfoResult.boxes[i].trackingNumber);
                        }
                        return uploadResult;
                    }


                }
                throw new Exception("下单失败" + result.message);
            }
        }

        public async Task<DJPrice> SS(Order_Order order, List<Order_OrderGoods> goods, Logistics_Channel channel, ExtendArg arg)
        {
            var orderRequest = ConvertRequest(order, goods, channel, arg.Order);
            var result = await Send<OrderRquest, DJPrice>(orderRequest, channel, "price");
            return result;
        }

        //如果好用，请收藏地址，帮忙分享。
        public class PriceBoxesItem
        {
            /// <summary>
            /// 
            /// </summary>
            public string chargeWeight { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string grossWeight { get; set; }
        }

        public class WarningsItem
        {
            /// <summary>
            /// 
            /// </summary>
            public string code { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string message { get; set; }
        }

        /// <summary>
        /// Price
        /// </summary>
        public class DJPrice
        {

            public string message
            {
                get; set;
            }

            /// <summary>
            /// 
            /// </summary>
            public List<PriceBoxesItem> boxes { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string chargeWeight { get; set; }
            /// <summary>
            /// 磅
            /// </summary>
            public string chargeWeightUnit { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string discountPercent { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public string finalCharge { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public bool success { get; set; }
            /// <summary>
            /// 
            /// </summary>
            public List<WarningsItem> warnings { get; set; }
        }

        public async Task<byte[]> DrawPdfLabel(UploadResult result, Logistics_Channel channel, Order_Order order, List<Order_OrderGoods> orderGoods)
        {
            return Convert.FromBase64String(result.DownloadUrl);
        }

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

}
