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

namespace XYY.Service.Standard.ChannelApi.FTL
{
    public class Api : IBaseApi
    {
        public string ServiceName => "FTL-OMS";

        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)
        {
            CreateOrderParam param = GetCreateOrderParam(channel, order);
            string host = channel.ApiHost;
            host = "https://gateway.ftlapp.cn/";
            string client_id = channel.ApiKey;
            string apiKey = channel.ApiSecret;
            string bearer = CreateBearer(apiKey);
            //host = "http://staging.ftl-oms.com";
            string url = $"/api/client/{client_id}/shipments";
            RestClient client = new RestClient(host);
            client.FollowRedirects = true;

            RestRequest request = new RestRequest(url);
            request.Method = Method.POST;

            request.AddJsonBody(param);
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(param);

            Debug.WriteLine(json);


            request.AddHeader("Authorization", bearer);

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

                CreateOrderResponse data = response.Data;

                if (data.status == "CREATED")
                {
                    if (!string.IsNullOrEmpty(data.trackingNumber))
                    {
                        var uploadResult = new UploadResult
                        {
                            IsSuccess = true,
                            ServiceOrderNumber = data.reference,
                            TrackingNumber = data.trackingNumber,
                            DownloadUrl = data.labelUrl,
                            LazyDownloadLabel = false
                        };
                        if (channel.ServiceChannelCode == "FTL_PLUS")
                        {
                            uploadResult.destinationCode = data.sortCode;
                        }
                        return uploadResult;

                    }
                    else
                    {
                        throw new Exception("下单api返回跟踪号为空");
                    }

                }
                else
                {
                    string msg = content;
                    throw new Exception($"下单出错 {msg}");
                }

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

        private CreateOrderParam GetCreateOrderParam(Logistics_Channel channel, Order_Order order)
        {

            int weight_g = order.OPWeight <= 0 ? order.CustomerWeight : order.OPWeight;
            if (order.OPWeight == 0 && order.CustomerId == 1101)
            {
                if (weight_g > 400)
                    weight_g = weight_g - 200;
            }

            decimal weight_kg = weight_g / 1000.0m;
            InRecipient recipient = CreateRecipient(order);
            CreateOrderParam param = new CreateOrderParam
            {
                client = channel.ApiKey,
                transporter = channel.ServiceChannelCode,
                reference = order.SystemNo,
                weight = weight_kg,
                recipient = recipient
            };
            if (order.CustomerId == 676)
            {
                param.reference = order.CustomerOrderNo;
            }
            return param;
        }

        private InRecipient CreateRecipient(Order_Order order)
        {
            string street = order.ReceiverStreet;
            string[] addresses = street.ToArray(35);
            if (addresses.Length > 3)
                throw new Exception("地址超长");
            string address1 = addresses[0];//max len 80,ascii only
            string address2 = addresses.Length > 1 ? addresses[1] : null;
            string address3 = addresses.Length > 2 ? addresses[2] : null;

            if (!string.IsNullOrEmpty(order.ReceiverCity))
            {
                order.ReceiverCity = order.ReceiverCity.Replace("-", " ");
            }



            InRecipient recipient = new InRecipient
            {
                city = order.ReceiverCity,
                country = order.ReceiverCountryCode,
                name = order.ReceiverName,
                phoneNumber = !string.IsNullOrEmpty(order.ReceiverPhone) ? order.ReceiverPhone : "11111111",
                street1 = address1,
                street2 = address2,
                street3 = address3,
                zipcode = order.ReceiverZipCode
            };

            if (recipient.country == "FR")
            {
                recipient.city = ToENS(recipient.city);
                recipient.name = ToENS(recipient.name);
            }

            return recipient;
        }


        private string ToENS(string FRS)
        {
            if (!string.IsNullOrEmpty(FRS))
            {
                FRS = FRS.Normalize(NormalizationForm.FormC);
                return FRS;

            }
            else
                return FRS;

        }

        public async Task<byte[]> DrawPdfLabel(UploadResult result, Logistics_Channel channel, Order_Order order, List<Order_OrderGoods> orderGoods)
        {
            byte[] data = await Task.Run(() =>
            {

                string clientId = channel.ApiKey;
                string trackingNumber = result.TrackingNumber;
                string host = channel.ApiHost;
                host = "https://gateway.ftlapp.cn/";
                string url = $"/api/client/{clientId}/shipments/{trackingNumber}/label";
                string apiKey = channel.ApiSecret;
                string bearer = CreateBearer(apiKey);
                try
                {
                    string labelUrl = $"{host}{url}";
                    if (!string.IsNullOrEmpty(result.DownloadUrl))
                    {
                        if(result.DownloadUrl == "https://s3-oprocloud.ftl-oms.com/ ")
                        {
                            result.DownloadUrl = "https://ftl-oms-production.s3.cn-northwest-1.amazonaws.com.cn/label/";
                        }
                        labelUrl = result.DownloadUrl;
                    }

                    WebClient wc = new WebClient();
                    var data = wc.DownloadData(labelUrl);
                    return data;
                }
                catch (WebException ex)
                {
                    Console.WriteLine($"{host}{url}" + ":" + bearer);
                    throw ex;
                }
            });
            return data;
        }

        private string CreateBearer(string apiKey)
        {
            string bearer = $"Bearer {apiKey}";
            return bearer;
        }

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