using Dapper;
using Grpc.Core;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using XYY.Service.Standard.Order;
using XYY.Model.Standard.Order;
using XYY.Model.Standard.MpsOrder;
using XYY.Model.Standard;

namespace XYY.gRpc.Order
{
    public class MoreThanOneTicketOrderService : MoreThanOneTicketOrders.MoreThanOneTicketOrdersBase
    {
        IOrderNumberService _orderSerice;
        XYY.Core.Standard.AliYun.IAliYunPostFileSerivce _aliYunPostFile;
        XYY.Core.Standard.Data.Infrastructure.IUnitOfWork unitOfWork;
        public MoreThanOneTicketOrderService(IOrderNumberService orderSerice, Core.Standard.AliYun.IAliYunPostFileSerivce aliYunPostFile, Core.Standard.Data.Infrastructure.IUnitOfWork unitOfWork)
        {
            _orderSerice = orderSerice;
            _aliYunPostFile = aliYunPostFile;
            this.unitOfWork = unitOfWork;
        }

        private async Task<MTOTOrderResult> GetMTOTOrderInfo(MTOROrderRequest request)
        {
            MTOTOrderResult result = new MTOTOrderResult();
            List<string> number = _orderSerice.GetNumber(1);

            for (int i = 0; i < request.Boxs.Count; i++)
            {
                result.Boxs.Add(new MTOTOrderResultBox
                {
                    BoxNumber = request.Boxs[i].BoxNumber,
                    TrackingNumber = number[0].Replace("XYYEX", "A").Replace("YQ", "") + (i + 1).ToString("000")
                });
            }
            result.TrackingNumber = number[0];
            MemoryStream ms = new MemoryStream();
            Rectangle pageSize = new Rectangle(285f, 285f);
            using (Document document = new Document(pageSize, 10f, 10f, 5f, 10f))
            {
                document.AddTitle("XingYunYI LABEL PDF");
                PdfWriter writer = PdfWriter.GetInstance(document, ms);
                writer.CloseStream = false;
                document.AddSubject("");
                document.AddKeywords("LABEL,EXPRESS,XingYunYI");
                document.AddCreator("XingYunYI");
                document.AddAuthor("XingYunYI");
                document.Open();
                PdfContentByte cb = writer.DirectContent;
                //面单生成
                for (int i = 0; i < request.Boxs.Count; i++)
                {
                    //字体
                    BaseFont stsong = BaseFont.CreateFont(
                    "C:\\WINDOWS\\FONTS\\STSONG.TTF",
                    BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

                    BaseFont baseTahomaBoldFont = BaseFont.CreateFont(
                   "C:\\WINDOWS\\FONTS\\TAHOMABD.TTF",
                   BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

                    Font YH_10 = FontFactory.GetFont("微软雅黑", 10, BaseColor.BLACK);
                    Font YH_27 = FontFactory.GetFont("微软雅黑", 27, BaseColor.BLACK);
                    Font YH_30 = FontFactory.GetFont("微软雅黑", 30, BaseColor.BLACK);
                    YH_30.SetStyle("bold");

                    cb.SetLineWidth(1f);
                    cb.MoveTo(0f, 225f);

                    cb.LineTo(285f, 225f);
                    cb.Stroke();

                    document.Add(new Phrase($" {request.CountryCode}", YH_27));

                    Font stsong_20 = new iTextSharp.text.Font(stsong, 20);
                    stsong_20.SetStyle("bold");

                    document.Add(new Phrase($"     {request.ChannelName}" + "  ", stsong_20));

                    iTextSharp.text.Font stsong_30 = new iTextSharp.text.Font(stsong, 30);
                    stsong_30.SetStyle("bold");

                    document.Add(new Paragraph("  ", FontFactory.GetFont("微软雅黑", 13, BaseColor.BLACK)));

                    document.Add(new Paragraph($"To:{request.Name}", new iTextSharp.text.Font(baseTahomaBoldFont, 15)));
                    document.Add(new Paragraph($"{request.Stree} {request.City} {request.State} {request.ZipCode}", new iTextSharp.text.Font(baseTahomaBoldFont, 10)));
                    document.Add(new Paragraph($"{request.Phone}", FontFactory.GetFont("微软雅黑", 13, BaseColor.BLACK)));

                    Barcode128 code128 = new Barcode128
                    {
                        Code = result.Boxs[i].TrackingNumber,
                        CodeType = iTextSharp.text.pdf.Barcode.CODE128,
                        X = 1f,
                        BarHeight = 35f,
                    };


                    iTextSharp.text.Image img = code128.CreateImageWithBarcode(cb, null, null);

                    img.SetAbsolutePosition(document.PageSize.Width / 5f,
                          document.PageSize.Height - 225f);

                    img.Alignment = iTextSharp.text.Image.ALIGN_LEFT;
                    document.Add(img);

                    iTextSharp.text.Font stsong_15 = new iTextSharp.text.Font(stsong, 15);
                    BaseFont font = BaseFont.CreateFont(@"C:\WINDOWS\Fonts\simhei.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);

                    cb.BeginText();
                    cb.SetFontAndSize(font, 12);
                    cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, $"Ref:{request.CustomerOrderNo} ", 5f, 40f, 0);
                    cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, $"Ref No.1:{result.TrackingNumber} ", 5f, 30f, 0);
                    cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, $"BoxNo:{request.Boxs[i].BoxNumber} ", 5f, 20f, 0);
                    cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT,
                        $"{i + 1}/{request.Boxs.Count} {request.Boxs[i].Weight}Kg {request.Boxs[i].Length}x{request.Boxs[i].Width}x{request.Boxs[i].Height}", 170f, 10f, 0);
                    cb.EndText();
                    if (i != result.Boxs.Count - 1)
                        document.NewPage();
                }
            }
            ms.Position = 0;
            result.LabelPath = _aliYunPostFile.PostHttpFile(ms, result.TrackingNumber + ".pdf");
            ms.Close();
            return result;
        }

        public override async Task<MTOTOrderResult> Create(MTOROrderRequest request, ServerCallContext context)
        {
            var order = await GetMTOTOrderInfo(request);
            await AsyncDb(request, order);
            //生成订单 
            return order;
        }

        private async Task AsyncDb(MTOROrderRequest request, MTOTOrderResult resutl)
        {
            var order = new Order_Order
            {
                CustomerOrderNo = request.CustomerOrderNo,
                ReceiverCountryCode = request.CountryCode,
                ChannelId = request.ChannelId,
                CreateOrderChannelId = request.ChannelId,
                CustomerId = request.CustomerId,
                CustomerWeight = request.Weight,
                ServiceLabelUrl = resutl.LabelPath,
                ReceiverCity = request.City,
                ReceiverState = request.State,
                ReceiverCompany = request.ReceiverCompany,
                ReceiverName = request.Name,
                ReceiverPhone = request.Phone,
                ReceiverEmail = string.Empty,
                ReceiverStreet = request.Stree,
                ReceiverZipCode = request.ZipCode,
                ReissueStatus = ReissueStatus.无,
                IsOnline = false,
                IsTransfer = true,
                OriginServiceLabelUrl = resutl.LabelPath,
                SystemNo = resutl.TrackingNumber,
                TransferNumber = resutl.TrackingNumber,
                TrackingNumber = resutl.TrackingNumber,
                CreateTime = DateTime.Now,
                OrderTime = DateTime.Now,
                SenderName = string.Empty,
                SenderCity = string.Empty,
                SenderCompany = string.Empty,
                SenderCountryCode = string.Empty,
                SenderCountryName = string.Empty,
                SenderEmail = string.Empty,
                SenderPhone = string.Empty,
                SenderState = string.Empty,
                SenderStreet = string.Empty,
                SenderZipCode = string.Empty,
                OrderStatus = 1,
                SealUserId = 1,
                SealCompanyId = 1,
            };

            //开启内部事务
            if (unitOfWork.Connection.State != System.Data.ConnectionState.Open)
                unitOfWork.Connection.Open();
            unitOfWork.Transaction = unitOfWork.Connection.BeginTransaction();
            try
            {
                var customer = (await unitOfWork.QueryBySqlAsync<dynamic>("select * from User_Customer where id = " + order.CustomerId)).FirstOrDefault();
                if (customer != null)
                {
                    order.SealUserId = customer.SalesmanUserId;
                    order.SealCompanyId = customer.BranchCompanyId;
                }
                if (await unitOfWork.IsExistsAsync<Order_Order>(x => x.OrderStatus >0 && x.CustomerOrderNo == order.CustomerOrderNo))
                    throw new Exception("客户单号重复");

                string boxSql = $@"select a.*,c.CustomerId,c.CreateOrderChannelId from Order_MpsOrderBox(nolock)a join Order_MpsOrder(nolock)b on a.MpsOrderId=b.Id
 join Order_Order(nolock) c on c.id=b.OrderId and c.OrderStatus>0 
	where BoxNumber in @boxnumbers ";
                var dbBoxInfo = await unitOfWork.QueryBySqlAsync<Order_MpsOrderBox>(boxSql, null, new
                {
                    boxnumbers = request.Boxs.Select(x => x.BoxNumber).ToList()
                });
                if (dbBoxInfo!=null&& dbBoxInfo.Count()>0) { throw new Exception("以下箱号已存在，请修改箱号后重试："+string.Join('|', dbBoxInfo.Select(x=>x.BoxNumber))); }
                order.MpsOrderId = request.MpsOrderId;
                int orderId = (int)await unitOfWork.InsertAsync(order);
                //更新草稿
                await unitOfWork.UpdateByConditionAsync<Order_DraftOrder, bool>(x => x.Id == request.DraftOrderId, new { Status = DraftOrderStatus.Finished });
                //更新一票多件信息
                await unitOfWork.UpdateByConditionAsync<Order_MpsOrder, bool>(x => x.Id == request.MpsOrderId,
                    new { OrderId = orderId, TransferNumber = resutl.TrackingNumber, Status =MpsOrderStatus.收件 });
                //更新一票多件箱子信息
                for (int i = 0; i < request.Boxs.Count; i++)
                {
                    await unitOfWork.UpdateByConditionAsync<Order_MpsOrderBox, bool>(x => x.Id == request.Boxs[i].BoxId, new
                    {
                        BoxServiceNumber = resutl.Boxs[i].TrackingNumber
                    });
                }
                //添加计费信息
                await unitOfWork.ExecuteAsync($@"insert Order_Fee(OrderId,OPWeight,ICWeight,ICFreight,ICCodFee,CreateTime) values({orderId}, 0, 0, 0, 0, GETDATE())");
                //物流轨迹 创建订单
                await unitOfWork.ExecuteStoredProcedureAsync("sp_FBATrackingLogAdd", new { @Status = 1, @OrderId = orderId, @TriggerTime = DateTime.Now });
                //提交事务
                unitOfWork.Commit();
            }
            catch (Exception ex)
            {
                //回滚事务
                unitOfWork.Rollback();
                await unitOfWork.UpdateByConditionAsync<Order_DraftOrder, bool>(x => x.Id == request.DraftOrderId, new { Status = DraftOrderStatus.Failed, ErrorMessage = ex.Message });

                throw ex;
            }


        }
    }
}