using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XYY.Data.Standard.Order;
using XYY.Model.Standard.Channel;
using XYY.Model.Standard.Order;
using XYY.Service.Standard.ChannelApi.Base;

namespace XYY.Service.Standard.ChannelApi.JianAiMaoYi
{
    public partial class Api : IBaseApi
    {
        ILogger<Api> _logger;
        IUser_CustomerDeclarationsRepository _CustomerDeclarationsRepository;
        public Api(ILogger<Api> logger, IUser_CustomerDeclarationsRepository CustomerDeclarationsRepository)
        {
            _logger = logger;
            _CustomerDeclarationsRepository = CustomerDeclarationsRepository;
        }
        public string ServiceName { get => "FedexJA"; }
        public Task<List<string>> Confims(List<OrderConfimRequest> order, Logistics_Channel channel)
        {
            throw new NotImplementedException();
        }

        public void CannelOrders(List<string> systemNO)
        {
            throw new NotImplementedException();
        }
        public void CannelOrdersByModel(logistics_ChannelCancel logistics_ChannelCancel)
        {
            throw new NotImplementedException();
        }

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

        public async Task<UploadResult> DataUpload(Order_Order order, List<Order_OrderGoods> goods, Logistics_Channel channel, ExtendArg arg)
        {
            //执行之前先判断 材质
            if (goods.Any(x => x.EnName.Contains("锌合金") || x.EnName.Contains("铝合金") || x.EnName.Contains("铁"))) { throw new Exception("该渠道仅允许服务类产品"); }

            string sign = channel.ApiKey;
            string orderHost = channel.ApiHost;
            var post = await ConvertOrder(order, goods, channel);
            string json = JsonConvert.SerializeObject(post);
            RestClient client = new RestClient(orderHost);
            RestRequest request = new RestRequest(Method.POST);
            request.AddHeader("Content-Type", "application/json");
            request.AddParameter("application/json", json, ParameterType.RequestBody);
            var response = client.Execute(request);
            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var result = JsonConvert.DeserializeObject<DataUploadResult>(response.Content);
                if (result.statusCode != "success")
                {
                    _logger.LogError("FedexJA下单失败:{@Request},{@Response}", request.Body, result);
                    return new UploadResult { Error = "FedexJA下单失败:" + response.Content };
                }
                else
                {
                    if (result.returnDatas.FirstOrDefault().statusCode != "success") { return new UploadResult { Error = "FedexJA下单失败:" + result.returnDatas?.FirstOrDefault()?.message }; }
                    _logger.LogError("FedexJA下单成功:{@Response}", result);
                    return new UploadResult
                    {
                        IsSuccess = true,
                        TrackingNumber = result.returnDatas.FirstOrDefault().trackNumber,
                        ServiceOrderNumber = result.returnDatas.FirstOrDefault().corpBillid,
                    };
                }
            }
            else
            {
                return new UploadResult { Error = "FedexJA下单失败:" + response.Content ?? response.ErrorMessage };
            }
        }
        private async Task<DataUploadInput> ConvertOrder(Order_Order order, List<Order_OrderGoods> goods, Logistics_Channel channel)
        {
            decimal orderWeight = order.CustomerWeight / 1000.0M;

            DataUploadInput post = new DataUploadInput();
            post.Verify = new Verify()
            {
                Clientid = channel.ApiKey,
                Token = channel.ApiSecret,
            };
            OrderDatasItem orderDatas = new OrderDatasItem()
            {
                CustomerNumber = order.SystemNo.Replace("XYYEX", "A"),
                ChannelCode = channel.ServiceChannelCode,
                CountryCode = order.ReceiverCountryCode,
                TotalWeight = orderWeight.ToString(),// (averageWeight * goods.Count).ToString(),
                TotalValue = goods.Sum(x => x.DeclareFee*x.Quantity).ToString(),
                GoodsType = channel.ServiceChannelCode == "DZ691IPPAK" ? "PAK" : "WPX",
            };
            orderDatas.Recipient = new Recipient()
            {
                Name = order.ReceiverName,
                Company = order.ReceiverCompany,
                Addres1 = order.ReceiverStreet,
                Post = order.ReceiverZipCode,
                Tel = order.ReceiverPhone,
                Mobile = order.ReceiverPhone,
                Province = order.ReceiverState,
                City = order.ReceiverCity,
                Email = order.ReceiverEmail,
            };
            orderDatas.Sender = new Sender();//无需赋值
            if (channel.ServiceChannelCode == "DZ691IPPAK")
            {
                orderDatas.Volumes.Add(new VolumesItem() { Weight = orderWeight.ToString(), });
            }
            else
            {
                orderDatas.Volumes.Add(new VolumesItem() { Weight = orderWeight.ToString(), Length = order.Length.ToString(), Width = order.Width.ToString(), Height = order.Height.ToString() });
            }
            orderDatas.TaxPayData = new TaxPayData();
            orderDatas.FeePayData = new FeePayData();

            //合并同品名数据
            var goodsGroup = goods.GroupBy(x => new { x.CnName, x.EnName });
            var fedexNames = await _CustomerDeclarationsRepository.QueryAsync(x => x.Fedex);//材质名称替换

            var totalGoodsCount = goods.Sum(g => g.Quantity);
            decimal averageWeight = Math.Floor(order.CustomerWeight / (decimal)totalGoodsCount) / 1000.0m;//平均重量

            foreach (var item in goodsGroup)
            {
                var fedexName = fedexNames.Where(x => x.CustomerCnName == item.Key.CnName)?.FirstOrDefault();
                if (fedexName == null) { throw new Exception($"中文品名[{item.Key.CnName}],无替换数据！"); }
                //var tempGoods = goods.Where(x => x.CnName == item.Key.CnName && x.EnName == item.Key.EnName).ToList();
                //var tempWeight = tempGoods.Sum(x => x.Weight)/1000.0M;
                orderDatas.OrderItems.Add(new OrderItemsItem()
                {
                    Cnname = fedexName.DeclarationOfChineseName + " " + item.Key.CnName,
                    Enname = fedexName.DeclarationOfEnglishName + " " + item.Key.EnName,
                    Price = item.Average(x => x.DeclareFee).ToString(),
                    Weight = averageWeight.ToString(),
                    Num = item.Sum(g => g.Quantity).ToString(),
                    Money = item?.FirstOrDefault()?.DeclareCurrency ?? "USD",
                    CustomsCode = item.Where(x => !string.IsNullOrEmpty(x.HsCode))?.FirstOrDefault()?.HsCode ?? "",
                    PeihuoInfo = item.Where(x => !string.IsNullOrEmpty(x.GoodsNumber))?.FirstOrDefault()?.GoodsNumber ?? "",
                });
            }
            post.OrderDatas.Add(orderDatas);
            return post;
        }
        public async Task<byte[]> DrawPdfLabel(UploadResult result, Logistics_Channel channel, Order_Order order, List<Order_OrderGoods> orderGoods)
        {
            IRestClient client = new RestClient(channel.ServiceTrackingUrl);
            IRestRequest request = new RestRequest(Method.POST);
            request.AddHeader("Content-Type", "application/json");

            DrawPdfLabelInput input = new DrawPdfLabelInput();
            input.Verify = new Verify() { Clientid = channel.ApiKey, Token = channel.ApiSecret };
            input.CorpBillidDatas.Add(new CorpBillidDatasItem() { CorpBillid = order.ServicesOrderNo });

            string json = JsonConvert.SerializeObject(input);
            request.AddParameter("application/json", json, ParameterType.RequestBody);
            var response = await client.ExecuteAsync(request);
            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var requestResult = JsonConvert.DeserializeObject<DrawPdfLabelResult>(response.Content);
                if (requestResult.statusCode == "success")
                {
                    string labelUrl = requestResult.url;
                    RestClient client2 = new RestClient();
                    RestRequest req = new RestRequest(labelUrl);
                    return client2.DownloadData(req);
                }
                else
                {
                    throw new Exception("面单下载失败" + requestResult.message);
                }
            }
            else
            {
                throw new Exception("面单下载失败" + response.ErrorMessage ?? response.Content);
            }
        }

    }
}
