using iTextSharp.text;
using iTextSharp.text.pdf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CCDCount.DLL.Tools
{
    public class PDFGenerateTools
    {
        /// <summary>
        /// 是否保存标志量
        /// </summary>
        public bool IsSave = false;
        /// <summary>
        /// 文档对象
        /// </summary>
        private Document document = new Document(PageSize.A4);
        /// <summary>
        /// 字体位置
        /// </summary>
        string fontPath = @"C:\Windows\Fonts\MSYH.ttc,0";  // 微软雅黑
        /// <summary>
        /// 字体实例
        /// </summary>
        BaseFont baseFont = null;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="outputPath">PDF生成位置</param>
        public PDFGenerateTools(string outputPath)
        {
            PdfWriter.GetInstance(document, new FileStream(outputPath, FileMode.Create));
            document.Open();
            baseFont = BaseFont.CreateFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        }

        /// <summary>
        /// 插入文本
        /// </summary>
        /// <param name="StrText">插入的文本</param>
        public void InsertText(string StrText)
        {
            if (IsSave)
            {
                return;
            }
            Font FontValue = new Font(baseFont, 12);
            Paragraph TextValue = new Paragraph(StrText, FontValue);
            TextValue.Alignment = Element.ALIGN_CENTER;
            document.Add(TextValue);
        }

        /// <summary>
        /// 插入文本
        /// </summary>
        /// <param name="StrText">插入的文本</param>
        /// <param name="FontSize">字体的字号</param>
        public void InsertText(string StrText, int FontSize)
        {
            if (IsSave)
            {
                return;
            }
            Font FontValue = new Font(baseFont, FontSize);
            Paragraph TextValue = new Paragraph(StrText, FontValue);
            TextValue.Alignment = Element.ALIGN_CENTER;
            document.Add(TextValue);
        }

        /// <summary>
        /// 插入文本
        /// </summary>
        /// <param name="StrText">插入的文本</param>
        /// <param name="FontSize">字体的字号</param>
        /// <param name="Alignment">对齐方式</param>
        public void InsertText(string StrText, int FontSize, int Alignment)
        {
            if (IsSave)
            {
                return;
            }
            Font FontValue = new Font(baseFont, FontSize);
            Paragraph TextValue = new Paragraph(StrText, FontValue);
            if (Alignment == 1)
            {
                TextValue.Alignment = Element.ALIGN_LEFT;
            }
            else if (Alignment == 2)
            {
                TextValue.Alignment = Element.ALIGN_RIGHT;
            }
            else if (Alignment == 3)
            {
                TextValue.Alignment = Element.ALIGN_CENTER;
            }
            else
            {
                Console.WriteLine("未定义对齐方式");
            }
            document.Add(TextValue);
        }

        /// <summary>
        /// 插入图片
        /// </summary>
        /// <param name="imagePath">图片路径</param>
        public void InsertImage(string imagePath)
        {
            if (IsSave)
            {
                return;
            }
            Font FontValue = new Font(baseFont, 12);
            // 插入图片
            try
            {
                Image img = Image.GetInstance(imagePath);
                img.ScaleToFit(500, 300);
                img.Alignment = Element.ALIGN_CENTER;
                document.Add(img);
            }
            catch (Exception ex)
            {
                document.Add(new Paragraph("图片加载失败: " + ex.Message));
            }
        }

        /// <summary>
        /// 插入图片
        /// </summary>
        /// <param name="imagePath">图片路径</param>
        public void InsertImage(byte[] imageBytes)
        {
            if (IsSave)
            {
                return;
            }
            Font FontValue = new Font(baseFont, 12);
            // 插入图片
            try
            {
                Image img = Image.GetInstance(imageBytes);
                img.ScaleToFit(500, 300);
                img.Alignment = Element.ALIGN_CENTER;
                document.Add(img);
            }
            catch (Exception ex)
            {
                document.Add(new Paragraph("图片加载失败: " + ex.Message));
            }
        }

        /// <summary>
        /// 插入图片
        /// </summary>
        /// <param name="imagePath">图片路径</param>
        /// <param name="width">图片宽度</param>
        /// <param name="height">图片高度</param>
        public void InsertImage(string imagePath,float width,float height)
        {
            if (IsSave)
            {
                return;
            }
            Font FontValue = new Font(baseFont, 12);
            // 插入图片
            try
            {
                Image img = Image.GetInstance(imagePath);
                img.ScaleToFit(width, height);
                img.Alignment = Element.ALIGN_CENTER;
                document.Add(img);
            }
            catch (Exception ex)
            {
                document.Add(new Paragraph("图片加载失败: " + ex.Message));
            }
        }

        /// <summary>
        /// 插入图片
        /// </summary>
        /// <param name="imagePath">图片路径</param>
        /// <param name="width">图片宽度</param>
        /// <param name="height">图片高度</param>
        public void InsertImage(byte[] imageBytes, float width, float height)
        {
            if (IsSave)
            {
                return;
            }
            Font FontValue = new Font(baseFont, 12);
            // 插入图片
            try
            {
                Image img = Image.GetInstance(imageBytes);
                img.ScaleToFit(width, height);
                img.Alignment = Element.ALIGN_CENTER;
                document.Add(img);
            }
            catch (Exception ex)
            {
                document.Add(new Paragraph("图片加载失败: " + ex.Message));
            }
        }

        /// <summary>
        /// 插入表格
        /// </summary>
        /// <param name="dataList">数据列表</param>
        /// <param name="tableName">表名</param>
        public void InsertTable<T>(List<T> dataList, string tableName = "表头") where T : class
        {
            if (IsSave)
            {
                return;
            }

            if (dataList == null || dataList.Count == 0)
            {
                return; // 如果数据为空则直接返回
            }

            Font FontValue = new Font(baseFont, 12);

            // 使用反射获取类的属性作为列
            var properties = typeof(T).GetProperties();
            PdfPTable table = new PdfPTable(properties.Length);
            table.WidthPercentage = 100; // 表格宽度为页面宽度的100%

            // 添加表名作为表头（跨所有列）
            PdfPCell cell = new PdfPCell(new Phrase(tableName, FontValue));
            cell.Colspan = properties.Length;
            cell.HorizontalAlignment = Element.ALIGN_CENTER;
            table.AddCell(cell);

            // 添加属性名作为列标题
            foreach (var prop in properties)
            {
                PdfPCell headerCell = new PdfPCell(new Phrase(prop.Name, FontValue));
                headerCell.HorizontalAlignment = Element.ALIGN_CENTER;
                table.AddCell(headerCell);
            }

            // 添加数据行
            foreach (var data in dataList)
            {
                foreach (var prop in properties)
                {
                    var value = prop.GetValue(data)?.ToString() ?? "";
                    table.AddCell(new Phrase(value, FontValue));
                }
            }

            // 将表格添加到文档
            document.Add(table);
        }

        /// <summary>
        /// 插入表格
        /// </summary>
        /// <param name="dataList">数据列表</param>
        /// <param name="tableName">表名</param>
        public void InsertTable<T>(List<T> dataList,List<string> Colspan,string tableName = "表头") where T : class
        {
            if (IsSave)
            {
                return;
            }

            if (dataList == null || dataList.Count == 0)
            {
                return; // 如果数据为空则直接返回
            }

            Font FontValue = new Font(baseFont, 12);

            // 使用反射获取类的属性作为列
            var properties = typeof(T).GetProperties();
            if(properties.Length != Colspan.Count) { return; }
            PdfPTable table = new PdfPTable(Colspan.Count);
            table.WidthPercentage = 100; // 表格宽度为页面宽度的100%

            // 添加表名作为表头（跨所有列）
            PdfPCell cell = new PdfPCell(new Phrase(tableName, FontValue));
            cell.Colspan = Colspan.Count;
            cell.HorizontalAlignment = Element.ALIGN_CENTER;
            table.AddCell(cell);

            // 添加属性名作为列标题
            foreach (var prop in Colspan)
            {
                PdfPCell headerCell = new PdfPCell(new Phrase(prop, FontValue));
                headerCell.HorizontalAlignment = Element.ALIGN_CENTER;
                table.AddCell(headerCell);
            }

            // 添加数据行
            foreach (var data in dataList)
            {
                foreach (var prop in properties)
                {
                    var value = prop.GetValue(data)?.ToString() ?? "";
                    table.AddCell(new Phrase(value, FontValue));
                }
            }

            // 将表格添加到文档
            document.Add(table);
        }

        /// <summary>
        /// 插入表格
        /// </summary>
        /// <param name="dataList">数据列表</param>
        /// <param name="tableName">表名</param>
        public void InsertTable<T>(List<T> dataList, List<string> Colspan,float[] ColWidth, string tableName = "表头") where T : class
        {
            if (IsSave)
            {
                return;
            }

            if (dataList == null || dataList.Count == 0)
            {
                return; // 如果数据为空则直接返回
            }

            Font FontValue = new Font(baseFont, 12);

            // 使用反射获取类的属性作为列
            var properties = typeof(T).GetProperties();
            if (properties.Length != Colspan.Count) { return; }
            PdfPTable table = new PdfPTable(Colspan.Count);
            table.SetWidths(ColWidth);
            table.WidthPercentage = 100; // 表格宽度为页面宽度的100%

            // 添加表名作为表头（跨所有列）
            PdfPCell cell = new PdfPCell(new Phrase(tableName, FontValue));
            cell.Colspan = Colspan.Count;
            cell.HorizontalAlignment = Element.ALIGN_CENTER;
            table.AddCell(cell);

            // 添加属性名作为列标题
            foreach (var prop in Colspan)
            {
                PdfPCell headerCell = new PdfPCell(new Phrase(prop, FontValue));
                headerCell.HorizontalAlignment = Element.ALIGN_CENTER;
                table.AddCell(headerCell);
            }

            // 添加数据行
            foreach (var data in dataList)
            {
                foreach (var prop in properties)
                {
                    var value = prop.GetValue(data)?.ToString() ?? "";
                    table.AddCell(new Phrase(value, FontValue));
                }
            }

            // 将表格添加到文档
            document.Add(table);
        }

        /// <summary>
        /// 插入表格
        /// </summary>
        /// <param name="dataList">数据列表</param>
        /// <param name="tableName">表名</param>
        public void InsertTable<T>(T data, string tableName = "表头") where T : class
        {
            if (IsSave)
            {
                return;
            }

            if (data == null)
            {
                return; // 如果数据为空则直接返回
            }

            Font FontValue = new Font(baseFont, 12);

            // 使用反射获取类的属性作为列
            var properties = typeof(T).GetProperties();
            PdfPTable table = new PdfPTable(2);
            table.WidthPercentage = 100; // 表格宽度为页面宽度的100%

            // 添加表名作为表头（跨所有列）
            PdfPCell cell = new PdfPCell(new Phrase(tableName, FontValue));
            cell.Colspan = 2;
            cell.HorizontalAlignment = Element.ALIGN_CENTER;
            table.AddCell(cell);

            PdfPCell headerCell1 = new PdfPCell(new Phrase("参数名", FontValue));
            headerCell1.HorizontalAlignment = Element.ALIGN_CENTER;
            table.AddCell(headerCell1);
            PdfPCell headerCell2 = new PdfPCell(new Phrase("参数值", FontValue));
            headerCell2.HorizontalAlignment = Element.ALIGN_CENTER;
            table.AddCell(headerCell2);

            //// 添加属性名作为列标题
            foreach (var prop in properties)
            {
                PdfPCell headerCell = new PdfPCell(new Phrase(prop.Name, FontValue));
                headerCell.HorizontalAlignment = Element.ALIGN_CENTER;
                table.AddCell(headerCell);

                var value = prop.GetValue(data)?.ToString() ?? "";
                PdfPCell RowValueCell = new PdfPCell(new Phrase(value, FontValue));
                RowValueCell.HorizontalAlignment = Element.ALIGN_CENTER;
                table.AddCell(RowValueCell);
            }

            // 将表格添加到文档
            document.Add(table);
        }

        /// <summary>
        /// 插入表格
        /// </summary>
        /// <param name="dataList">数据列表</param>
        /// <param name="tableName">表名</param>
        public bool InsertTable<T>(T data, List<string> Rowspan, string tableName = "表头") where T : class
        {
            bool Result = false;
            if (IsSave)
            {
                return false;
            }

            if (data == null)
            {
                return false; // 如果数据为空则直接返回
            }

            Font FontValue = new Font(baseFont, 12);

            // 使用反射获取类的属性作为列
            var properties = typeof(T).GetProperties();
            PdfPTable table = new PdfPTable(2);
            table.WidthPercentage = 100; // 表格宽度为页面宽度的100%

            // 添加表名作为表头（跨所有列）
            PdfPCell cell = new PdfPCell(new Phrase(tableName, FontValue));
            cell.Colspan = 2;
            cell.HorizontalAlignment = Element.ALIGN_CENTER;
            table.AddCell(cell);

            PdfPCell headerCell1 = new PdfPCell(new Phrase("参数名", FontValue));
            headerCell1.HorizontalAlignment = Element.ALIGN_CENTER;
            table.AddCell(headerCell1);
            PdfPCell headerCell2 = new PdfPCell(new Phrase("参数值", FontValue));
            headerCell2.HorizontalAlignment = Element.ALIGN_CENTER;
            table.AddCell(headerCell2);

            if (Rowspan.Count != properties.Length) { return false; }
            for (int i=0;i<properties.Length;i++)
            {
                PdfPCell RowNameCell = new PdfPCell(new Phrase(Rowspan[i], FontValue));
                RowNameCell.HorizontalAlignment = Element.ALIGN_CENTER;
                table.AddCell(RowNameCell);

                var value = properties[i].GetValue(data)?.ToString() ?? "";
                PdfPCell RowValueCell = new PdfPCell(new Phrase(value, FontValue));
                RowValueCell.HorizontalAlignment = Element.ALIGN_CENTER;
                table.AddCell(RowValueCell);
            }

            // 将表格添加到文档
            document.Add(table);
            Result = true;
            return Result;
        }

        /// <summary>
        /// 插入空白行
        /// </summary>
        public void InsertNewLine()
        {
            if (IsSave)
            {
                return;
            }
            document.Add(Chunk.NEWLINE);
        }

        /// <summary>
        /// 保存PDF文件
        /// </summary>
        public void SavePDF()
        {
            document.Close();
            IsSave = true;
        }
    }
}
