package com.hxhq.business.utils.pdf;

import com.hxhq.common.core.exception.ServiceException;
import com.hxhq.common.core.text.Convert;
import com.hxhq.common.core.utils.StringUtils;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.draw.LineSeparator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.*;

/**
 * pdf导出基类
 *
 * @author tanfei
 */
@Component
public class PdfBaseUtil {

    private static final Logger logger = LoggerFactory.getLogger(PdfBaseUtil.class);

    /**
     * 生成PDF文件完整路径（按年月日创建文件夹）
     *
     * @return 完整文件路径，
     */
    public static String getFilePath(String localFilePath,String  type) {
        // 1. 获取当前年月日并创建文件夹
        Date now = new Date();
        SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
        SimpleDateFormat monthFormat = new SimpleDateFormat("MM");
        SimpleDateFormat dayFormat = new SimpleDateFormat("dd");
        SimpleDateFormat timestampFormat = new SimpleDateFormat("yyyyMMddHHmmss");

        String year = yearFormat.format(now);
        String month = monthFormat.format(now);
        String day = dayFormat.format(now);
        String timestamp = timestampFormat.format(now) + UUID.randomUUID();

        // 2. 构建文件夹路径
        String folderPath = localFilePath + File.separator + year + File.separator + month + File.separator + day;

        // 3. 确保目录存在
        File dir = new File(folderPath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        // 4. 生成文件名
        String fileName =type+ "_" + timestamp + ".pdf";
        // 5. 完整文件路径
        return Paths.get(folderPath, fileName).toString();
    }

    /**
     * 添加标题
     *
     * @param document  PDF文档对象
     * @param titleText 标题文本
     * @param fontSize  字体大小
     */
    public static void addUnderlinedTitle(Document document, String titleText, float fontSize, Boolean hasLine)
            throws DocumentException, IOException {

        // 创建中文字体
        BaseFont baseFont = BaseFont.createFont(
                "STSong-Light",
                "UniGB-UCS2-H",
                BaseFont.EMBEDDED
        );

        Font titleFont = new Font(baseFont, fontSize, Font.NORMAL, BaseColor.BLACK);
        Font linFont = new Font(baseFont, fontSize, Font.NORMAL, BaseColor.BLACK);

        // 创建标题段落
        Paragraph titleParagraph = new Paragraph(titleText, titleFont);
        titleParagraph.setAlignment(Element.ALIGN_LEFT);
        titleParagraph.setSpacingAfter(5);
        document.add(titleParagraph);

        if (hasLine) {
            // 添加下划线
            LineSeparator underline = new LineSeparator(linFont);
            // 宽度占50%
            underline.setPercentage(100);
            // 线粗
            underline.setLineWidth(0.5f);
            underline.setAlignment(Element.ALIGN_LEFT);
            // 添加到文档
            document.add(underline);
        }
    }

    /**
     * 初始化
     *
     * @param document
     * @param fos
     * @param filePath
     * @param signText
     */
    public static Document init(Document document, FileOutputStream fos, String filePath, String signText, String headerText,Boolean showHaderLine) {
        try {
            // 创建PDF文档 设置文档边距，避免内容遮挡页眉页脚
            // 顶部边距（为页眉留出空间）
            float topMargin = 70;
            // 底部边距（为页脚留出空间）
            float bottomMargin = 60;
            // 左边距
            float leftMargin = 50;
            // 右边距
            float rightMargin = 50;

            document = new Document(PageSize.A4,
                    leftMargin, rightMargin, topMargin, bottomMargin);

            fos = new FileOutputStream(filePath);
            PdfWriter writer = PdfWriter.getInstance(document, fos);
            // 设置页面事件，每页添加文字页眉
            writer.setPageEvent(new PdfBaseUtil.TextHeaderEvent(signText, headerText,showHaderLine));
            // 5. 设置PDF属性
            document.addTitle("hxhq");
            document.addAuthor("hxhq");
            document.addCreator("hxhq");
            document.addCreationDate();
            document.open();
            return document;
        } catch (Exception e) {
            logger.error("生成失败", e);
            throw new ServiceException("生成失败: " + e.getMessage());
        }
    }

    /**
     * 创建表单
     *
     * @param document
     * @param data
     * @param count
     * @throws DocumentException
     * @throws IOException
     */
    public static void addFormTableColumns(Document document, Map<String, String> data, Integer count)
            throws DocumentException, IOException {

        // 创建3列表格
        PdfPTable table = new PdfPTable(count);
        table.setWidthPercentage(100);
        table.setSpacingAfter(10);

        // 设置等宽列
        float[] widths = new float[count];
        for (int i = 0; i < count; i++) {
            // 等宽
            widths[i] = 1.0f;
        }
        table.setWidths(widths);

        // 创建字体
        BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        Font labelFont = new Font(baseFont, 10, Font.NORMAL, BaseColor.BLACK);
        Font valueFont = new Font(baseFont, 10, Font.NORMAL, BaseColor.BLACK);

        // 将数据转换为List
        List<Map.Entry<String, String>> entries = new ArrayList<>(data.entrySet());

        // 每3个字段一组，每组一行
        for (int i = 0; i < entries.size(); i += count) {
            // 创建一行
            for (int j = 0; j < count; j++) {
                int index = i + j;

                if (index < entries.size()) {
                    Map.Entry<String, String> entry = entries.get(index);

                    // 创建单元格内容
                    Phrase cellContent = new Phrase();
                    cellContent.add(new Chunk(entry.getKey() + "：", labelFont));
                    cellContent.add(new Chunk(com.hxhq.common.core.utils.StringUtils.isBlank(entry.getValue()) ? "" : entry.getValue(), valueFont));

                    PdfPCell cell = new PdfPCell(cellContent);
                    // 无边框
                    cell.setBorder(Rectangle.NO_BORDER);
                    cell.setPadding(4);
                    cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                    cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                    // 最小高度
                    cell.setMinimumHeight(20);

                    table.addCell(cell);
                } else {
                    // 添加空单元格保持布局
                    PdfPCell emptyCell = new PdfPCell();
                    emptyCell.setBorder(Rectangle.NO_BORDER);
                    emptyCell.setMinimumHeight(20);
                    table.addCell(emptyCell);
                }
            }
        }

        document.add(table);
    }

    /**
     * 创建表格
     *
     * @param content
     * @param font
     * @return
     */
    public static PdfPCell createCell(String content, Font font) {
        PdfPCell cell = new PdfPCell(new Phrase(content, font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setPadding(6);
        cell.setMinimumHeight(25);
        return cell;
    }


    /**
     * 页面事件处理类 - 每页添加文字页眉
     */
    static class TextHeaderEvent extends PdfPageEventHelper {
        private Font footerFont;
        private String signText;
        private String headerText;
        private BaseFont baseFont;
        private Boolean showHaderLine=true;
        private int totalPages = 0;
        private PdfTemplate total;

        public TextHeaderEvent(String signText, String headerText,Boolean showHaderLine) throws Exception {
            try {
                this.showHaderLine = showHaderLine;
                this.signText = signText;
                this.headerText = headerText;
                // 创建字体（支持中文）
                this.baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                footerFont = new Font(baseFont, 10, Font.NORMAL, BaseColor.GRAY);
            } catch (Exception e) {
                footerFont = new Font(Font.FontFamily.HELVETICA, 10, Font.NORMAL, BaseColor.GRAY);
            }
        }

        @Override
        public void onOpenDocument(PdfWriter writer, Document document) {
            total = writer.getDirectContent().createTemplate(100, 16);
        }

        @Override
        public void onCloseDocument(PdfWriter writer, Document document) {
            totalPages = writer.getPageNumber();
            String totalPagesStr = String.valueOf(totalPages);

            // 重新创建合适宽度的模板
            BaseFont baseFont = footerFont.getBaseFont();
            float actualWidth = baseFont.getWidthPoint(totalPagesStr, footerFont.getSize());

            total.beginText();
            total.setFontAndSize(baseFont, footerFont.getSize());
            total.setTextMatrix(0, 0);
            total.showText(totalPagesStr);
            total.endText();
        }

        @Override
        public void onEndPage(PdfWriter writer, Document document) {
            try {
                PdfContentByte cb = writer.getDirectContent();

                // 获取页面尺寸
                Rectangle pageSize = document.getPageSize();
                float pageWidth = pageSize.getWidth();
                float pageHeight = pageSize.getHeight();

                // 设置页眉参数
                float topMargin = 30;     // 顶部边距
                float fontSize = 12;      // 字体大小

                // 计算文字宽度（用于居中）
                float textWidth = baseFont.getWidthPoint(signText, fontSize);

                // 计算居中位置
                float textX = (pageWidth - textWidth) / 2;
                float textY = pageHeight - topMargin;

                // 获取画布
                PdfContentByte canvas = writer.getDirectContent();

                int currentPage = writer.getPageNumber();
                float y = document.bottom() - 20;

                // 在每一页都重新计算，确保位置准确
                String pageText = "第 " + currentPage + " 页 / 共 ";
                BaseFont baseFont = footerFont.getBaseFont();

                // 计算页面文本宽度
                float pageTextWidth = baseFont.getWidthPoint(pageText, footerFont.getSize());

                // 临时用估计的总页数计算位置（等文档关闭后会被替换）
                String tempTotal = String.valueOf(writer.getPageNumber() + 5); // 估计值
                float totalWidth = baseFont.getWidthPoint(tempTotal, footerFont.getSize());

                // 计算起始位置
                float totalTextWidth = pageTextWidth + totalWidth +
                        baseFont.getWidthPoint(" 页", footerFont.getSize());
                float startX = (document.getPageSize().getWidth() - totalTextWidth) / 2;

                // 写入当前页信息
                ColumnText.showTextAligned(cb, Element.ALIGN_LEFT,
                        new Phrase(pageText, footerFont), startX, y, 0);

                // 添加总页数模板
                cb.addTemplate(total, startX + pageTextWidth, y);

                // 写入"页"字
                ColumnText.showTextAligned(cb, Element.ALIGN_LEFT,
                        new Phrase(" 页", footerFont), startX + pageTextWidth + totalWidth, y, 0);

                PdfContentByte content = writer.getDirectContentUnder(); // 在水印层添加

                // 设置透明度
                PdfGState gs = new PdfGState();
                float opacity = Convert.toFloat("0.3");
                gs.setFillOpacity(opacity);
                content.setGState(gs);

                // 设置字体和颜色
                content.setColorFill(BaseColor.RED);
                content.setFontAndSize(baseFont, fontSize);

                float width = pageSize.getWidth();
                float height = pageSize.getHeight();

                // 重复铺满水印
                addRepeatedWatermark(content, width, height, signText);

                // 添加页眉文字
                if(StringUtils.isNoneBlank(headerText)) {
                    canvas.beginText();
                    canvas.setFontAndSize(baseFont, fontSize);
                    canvas.setTextMatrix(textX, textY);
                    canvas.showText(headerText);
                    canvas.endText();

                    if(showHaderLine){
                        // 添加页眉分隔线（可选）
                        addHeaderLine(canvas, pageWidth, textY - 10);
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        /**
         * 添加水印
         *
         * @param content
         * @param width
         * @param height
         * @param signText
         */
        private void addRepeatedWatermark(PdfContentByte content, float width, float height, String signText) {
            // 计算文字尺寸
            float fontSize = Convert.toFloat("10");
            float textWidth = baseFont.getWidthPoint(signText, fontSize)+50;
            float textHeight = baseFont.getAscentPoint(signText, fontSize) -
                    baseFont.getDescentPoint(signText, fontSize);

            // 计算间距
            float stepX = textWidth + 70;
            float stepY = textHeight + 100;

            // 添加重复水印
            Integer two=2;
            for (float x = textWidth / two; x < width; x += stepX) {
                for (float y = textHeight / two; y < height; y += stepY) {
                    content.beginText();
                    content.showTextAligned(
                            Element.ALIGN_CENTER,
                            signText,
                            x,
                            y,
                            fontSize
                    );
                    content.endText();
                }
            }
        }

        /**
         * 添加页眉线
         *
         * @param canvas
         * @param pageWidth
         * @param yPos
         */
        private void addHeaderLine(PdfContentByte canvas, float pageWidth, float yPos) {
            canvas.setLineWidth(0.5f);
            canvas.moveTo(50, yPos);
            canvas.lineTo(pageWidth - 50, yPos);
            canvas.stroke();
        }
    }
}