using System.Dynamic;
using DynamicExpresso;
using iTextSharp.text;
using iTextSharp.text.pdf;
using Newtonsoft.Json.Linq;
namespace PdfSign;
public class SignService
{
    public static string PdfSign(List<SignOpt> signOpts, string pdfName)
    {
        var beforeFileName = pdfName; //签名之前文件名
        var afterFileName = pdfName + "_sign"; //签名之后文件名
        var idx = 0;
        foreach (var opt in signOpts)
        {
            //创建盖章后生成pdf
            var outputPdfStream =
                new FileStream(afterFileName + ".pdf", FileMode.Create, FileAccess.Write, FileShare.None);
            //读取原有pdf
            var pdfReader = new PdfReader(beforeFileName + ".pdf");
            var pdfStamper = new PdfStamper(pdfReader, outputPdfStream);
            //读取页数
            var pdfPageSize = pdfReader.NumberOfPages;
            //读取pdf文件第一页尺寸,得到 With 和 Height
            var size = pdfReader.GetPageSize(1);
            //通过表达式计算出签署的绝对坐标
            var locationX = Eval<float>(opt.LocationX, new { size.Width, size.Height });
            var locationY = Eval<float>(opt.LocationY, new { size.Width, size.Height });
            if (opt.LastPage)
            {
                //盖章在最后一页
                var pdfContentByte = pdfStamper.GetOverContent(pdfPageSize);
                var gs = new PdfGState
                {
                    FillOpacity = opt.Opacity
                };
                pdfContentByte.SetGState(gs);
                switch (opt.SignType.ToLower())
                {
                    case "image":
                        //获取图片
                        var image = Image.GetInstance(opt.FileName);
                        //设置图片比例
                        image.ScalePercent(opt.ScalePercent);
                        //设置图片的绝对位置,位置偏移方向为:左到右,下到上
                        image.SetAbsolutePosition(locationX, locationY);
                        //图片添加到文档
                        pdfContentByte.AddImage(image);
                        break;
                    case "text":
                        if (string.IsNullOrWhiteSpace(opt.Text))
                            continue;
                        var font = BaseFont.CreateFont();
                        var text = Eval<string>(opt.Text, new { Date = DateTime.Now.ToString("yyyy-MM-dd") });
                        //开始写入文本
                        pdfContentByte.BeginText();
                        pdfContentByte.SetColorFill(
                            new BaseColor(opt.FontColor.R, opt.FontColor.G, opt.FontColor.B));
                        pdfContentByte.SetFontAndSize(font, opt.FontSize);
                        pdfContentByte.SetTextMatrix(0, 0);
                        pdfContentByte.ShowTextAligned(Element.ALIGN_CENTER, text,
                            locationX, locationY, opt.Rotation);
                        pdfContentByte.EndText();
                        break;
                }
            }
            pdfStamper.Close();
            pdfReader.Close();
            idx++;
            if (idx >= signOpts.Count) continue;
            //文件名重新赋值
            beforeFileName = afterFileName;
            afterFileName += "_sign";
        }
        return afterFileName + ".pdf";
    }
    //计算动态表达式的值
    public static T? Eval<T>(string expr, object context)
    {
        if (string.IsNullOrWhiteSpace(expr))
            return default;
        var target = new Interpreter();
        var input = JObject.FromObject(context);
        target.SetVariable("input", input.ToObject<ExpandoObject>());
        return target.Eval<T>(expr);
    }
}