package com.hxhq.business.utils;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hxhq.business.domain.*;
import com.hxhq.business.utils.lang.TemplateUtil;
import com.hxhq.business.utils.pdf.PdfBaseUtil;
import com.hxhq.business.utils.pdf.PdfExportUtil;
import com.hxhq.common.core.text.Convert;
import com.hxhq.common.core.utils.DateUtils;
import com.hxhq.common.core.utils.StringUtils;
import com.hxhq.common.security.utils.SecurityUtils;
import com.hxhq.system.api.model.LoginUser;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
import java.util.Random;
import java.util.StringJoiner;

/**
 * 试验方法pdf导出
 *
 * @author HanLong
 */
@Component
public class StudyFormFillUtil {

    private static final Logger log = LoggerFactory.getLogger(StudyFormFillUtil.class);
    public static String language = "zh";
    /**
     * 资源映射路径 前缀
     */
    @Value("${file.prefix}")
    public String localFilePrefix;

    /**
     * 域名或本机访问地址
     */
    @Value("${file.domain}")
    public String domain;

    /**
     * 上传文件存储在本地的根路径
     */
    @Value("${file.path}")
    private String localFilePath;

    /**
     * 复制原有PDF的所有页面到新Document中
     */
    private static void copyOriginalPagesToDocument(Document doc, PdfWriter writer, PdfReader reader) throws DocumentException {
        int pageCount = reader.getNumberOfPages();
        // 获取直接内容画布
        PdfContentByte canvas = writer.getDirectContent();

        for (int i = 1; i <= pageCount; i++) {
            doc.newPage(); // 新建一页（与原PDF页面一一对应）
            // 5.5.11中通过PdfImportedPage导入原有页面
            PdfImportedPage importedPage = writer.getImportedPage(reader, i);
            // 将原有页面绘制到新文档的当前页
            canvas.addTemplate(importedPage, 0, 0);
        }
    }

    /**
     * 导出table
     *
     * @param headerText
     * @param fileDir
     * @return
     */
    public static String export(String version,String lang, String headerText, String srcPdf, String fileDir, List<StudyFormFillJcgj> jcgjList, List<StudyFormFillQmxx> qmxxList,Boolean jcgj) {
        language = lang;
        Document document = null;
        FileOutputStream fos = null;
        String filePath = "";
        String fileName = "";
        try {
            // 1. 生成文件名
            fileName = generateFileName();
            // 2. 确保目录存在
            File dir = new File(fileDir);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            // 3. 完整文件路径
            filePath = Paths.get(fileDir, fileName).toString();
            // 创建PDF文档 设置文档边距，避免内容遮挡页眉页脚
            // 1. 读取原有PDF，获取页面尺寸（保证新文档与原文档格式一致）
            PdfReader srcReader = new PdfReader(srcPdf);
            // 取第一页尺寸作为新文档尺寸
            Rectangle pageSize = srcReader.getPageSize(1);
            // 2. 初始化Document（iText 5的核心高层类）
            document = new Document(pageSize);
            fos = new FileOutputStream(filePath);
            // 3. 关联PdfWriter，绑定Document和输出流（5.5.11必须先创建Writer再open Document）
            PdfWriter writer = PdfWriter.getInstance(document, fos);
            // 设置页面事件，每页添加文字页眉
            String sign = "hxhq";
            LoginUser loginUser = SecurityUtils.getLoginUser();
            if (loginUser != null) {
                sign = loginUser.getSysUser().getNickName() + "   " + DateUtils.getTime();
            }
            writer.setPageEvent(new TextHeaderEvent(sign+"   "+version+"   ", headerText, false));
            // 4. 设置PDF属性
            document.addTitle("华西海圻");
            document.addAuthor("华西海圻");
            document.addCreator("华西海圻");
            document.addCreationDate();
            document.open();
            // 5. 复制原有PDF的所有页面到新Document中
            copyOriginalPagesToDocument(document, writer, srcReader);
            // 7. 表格设置到新的一页
            document.newPage();
            addQmxx(document, qmxxList, lang);
            if(jcgj){
                addJcgj(document, jcgjList, lang);
            }
        } catch (Exception e) {
            throw new RuntimeException("生成失败: " + e.getMessage());
        } finally {
            if (document != null) {
                document.close();
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    log.error("关闭文件流失败", e);
                }
            }
        }
        return fileName;
    }

    /**
     * 导出table
     *
     * @param headerText
     * @param fileDir
     * @return
     */
    public static String exportTb(String version,String lang, String headerText, String srcPdf, String fileDir) {
        language = lang;
        Document document = null;
        FileOutputStream fos = null;
        String filePath = "";
        String fileName = "";
        try {
            // 1. 生成文件名
            fileName = generateFileName();
            // 2. 确保目录存在
            File dir = new File(fileDir);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            // 3. 完整文件路径
            filePath = Paths.get(fileDir, fileName).toString();
            // 创建PDF文档 设置文档边距，避免内容遮挡页眉页脚
            // 1. 读取原有PDF，获取页面尺寸（保证新文档与原文档格式一致）
            PdfReader srcReader = new PdfReader(srcPdf);
            // 取第一页尺寸作为新文档尺寸
            Rectangle pageSize = srcReader.getPageSize(1);
            // 2. 初始化Document（iText 5的核心高层类）
            document = new Document(pageSize);
            fos = new FileOutputStream(filePath);
            // 3. 关联PdfWriter，绑定Document和输出流（5.5.11必须先创建Writer再open Document）
            PdfWriter writer = PdfWriter.getInstance(document, fos);
            // 设置页面事件，每页添加文字页眉
            String sign = "hxhq";
            LoginUser loginUser = SecurityUtils.getLoginUser();
            if (loginUser != null) {
                sign = loginUser.getSysUser().getNickName() + "   " + DateUtils.getTime();
            }
            writer.setPageEvent(new TextHeaderEvent(sign+"   "+version+"   ", headerText, false));
            // 4. 设置PDF属性
            document.addTitle("华西海圻");
            document.addAuthor("华西海圻");
            document.addCreator("华西海圻");
            document.addCreationDate();
            document.open();
            // 5. 复制原有PDF的所有页面到新Document中
            copyOriginalPagesToDocument(document, writer, srcReader);
        } catch (Exception e) {
            throw new RuntimeException("生成失败: " + e.getMessage());
        } finally {
            if (document != null) {
                document.close();
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    log.error("关闭文件流失败", e);
                }
            }
        }
        return fileName;
    }

    /**
     * 签名信息
     * 申请表单
     *
     * @param document
     * @param studyFormFillQmxxList
     * @throws IOException
     * @throws DocumentException
     */
    public static void addQmxx(Document document, List<StudyFormFillQmxx> studyFormFillQmxxList, String lang) throws IOException, DocumentException {
        language = lang;
        PdfBaseUtil.addUnderlinedTitle(document, getName("签名信息"), 10, true);
        // 9. 表头
        BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        Font headerFont = new Font(bfChinese, 10, Font.NORMAL);
        Font contentFont = new Font(bfChinese, 10, Font.NORMAL);

        // 8. 创建表格
        PdfPTable table = new PdfPTable(4);
        table.setWidthPercentage(100);
        table.setSpacingBefore(10);
        String[] headers = {getName("签名人"), getName("签名意义"), getName("签名时间"), getName("备注原因")};
        for (String header : headers) {
            PdfPCell cell = new PdfPCell(new Phrase(header, headerFont));
            cell.setPadding(8);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setBackgroundColor(BaseColor.WHITE);
            cell.setBorderWidth(1);
            table.addCell(cell);
        }
        if (studyFormFillQmxxList.size() > 0) {
            int rowNum = 0;
            for (StudyFormFillQmxx studyFormFillQmxx : studyFormFillQmxxList) {
                // 交替行颜色
                if (rowNum % 2 == 0) {
                    table.getDefaultCell().setBackgroundColor(BaseColor.WHITE);
                } else {
                    table.getDefaultCell().setBackgroundColor(BaseColor.WHITE);
                }
                table.addCell(PdfBaseUtil.createCell(studyFormFillQmxx.getQmrMc(), contentFont));
                table.addCell(PdfBaseUtil.createCell("en".equals(language) ? studyFormFillQmxx.getQmyyEn() : studyFormFillQmxx.getQmyy(), contentFont));
                table.addCell(PdfBaseUtil.createCell(PdfExportUtil.parseDateToStr(studyFormFillQmxx.getCreateTime()), contentFont));
                table.addCell(PdfBaseUtil.createCell(studyFormFillQmxx.getRemark(), contentFont));
                rowNum++;
            }
        }
        document.add(table);
    }

    /**
     * 稽查轨迹
     * 申请表单
     *
     * @param document
     * @param studyFormFillJcgjList
     * @throws IOException
     * @throws DocumentException
     */
    public static void addJcgj(Document document, List<StudyFormFillJcgj> studyFormFillJcgjList, String lang) throws IOException, DocumentException {
        language = lang;
        PdfBaseUtil.addUnderlinedTitle(document, getName("稽查轨迹"), 10, true);
        for (StudyFormFillJcgj jcgj : studyFormFillJcgjList) {
            StringJoiner result = new StringJoiner(", ");
            if ("en".equals(lang)) {
                PdfBaseUtil.addUnderlinedTitle(document, PdfExportUtil.parseDateToStr(jcgj.getCreateTime()) + "     " + jcgj.getJcmcEn(), 10, false);
                if (StringUtils.isNoneBlank(jcgj.getJcnrEn())) {
                    ObjectMapper mapper = new ObjectMapper();
                    JsonNode jsonArray = mapper.readTree(jcgj.getJcnrEn());
                    for (JsonNode node : jsonArray) {
                        if (node.get("name") != null) {
                            String name = node.get("name").asText();
                            if(!name.equals("url")&&!name.equals("oldUrl")){
                                String value = node.get("value") != null ? node.get("value").asText() : "";
                                result.add(name + "：" + value);
                            }
                        }
                    }
                }
            } else {
                PdfBaseUtil.addUnderlinedTitle(document, PdfExportUtil.parseDateToStr(jcgj.getCreateTime()) + "     " + jcgj.getJcmc(), 10, false);
                if (StringUtils.isNoneBlank(jcgj.getJcnr())) {
                    ObjectMapper mapper = new ObjectMapper();
                    JsonNode jsonArray = mapper.readTree(jcgj.getJcnr());
                    for (JsonNode node : jsonArray) {
                        if (node.get("name") != null) {
                            String name = node.get("name").asText();
                            if(!name.equals("url")&&!name.equals("oldUrl")){
                                String value = node.get("value") != null ? node.get("value").asText() : "";
                                result.add(name + "：" + value);
                            }
                        }
                    }
                }
            }

            if (StringUtils.isNoneBlank(jcgj.getRemark())) {
                result.add(getName("备注") + "：" + jcgj.getRemark());
            }
            if (StringUtils.isNoneBlank(jcgj.getQmrMc())) {
                result.add(getName("签名人") + "：" + jcgj.getQmrMc());
            }
            PdfBaseUtil.addUnderlinedTitle(document, result.toString(), 10, false);
        }
    }


    /**
     * 获取名称
     *
     * @param name
     * @return
     */
    public static String getName(String name) {
        return "en".equals(language) ? TemplateUtil.getEn(name) : name;
    }


    /**
     * 创建表格
     */
    private 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;
    }


    /**
     * 生成文件名
     */
    private static String generateFileName() {
        Random random = new Random();
        String timestamp = DateUtils.dateTimeNow("yyyyMMddHHmmss");
        return String.format("%s_%s.pdf", timestamp, random.nextInt(1000));
    }


    /**
     * 页面事件处理类 - 每页添加文字页眉
     */
    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 = 15;     // 顶部边距
                float fontSize = 12;      // 字体大小

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

                // 计算居中位置
                float textX = (pageSize.getLeft() + pageSize.getRight()) / 2;
                float textY = pageHeight - topMargin;

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

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

                // 在每一页都重新计算，确保位置准确
                String pageText =language.equals("zh")? (signText+ " 页 " + currentPage + " / "):(signText+ " page " + currentPage + " of ");
                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(language.equals("zh")? " 页":" page", footerFont.getSize());
                float startX = (document.getPageSize().getWidth() - totalTextWidth)+(language.equals("zh")?Float.parseFloat("0.0"):Float.parseFloat("10.0")) ;

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

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

                // 写入"页"字
//                if(language.equals("zh")){
//                    ColumnText.showTextAligned(cb, Element.ALIGN_LEFT,
//                            new Phrase(" 页", footerFont), startX + pageTextWidth + totalWidth-10, 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)) {
                    float pageTextWidth1 = baseFont.getWidthPoint(headerText, footerFont.getSize());
                    float startX1 = (document.getPageSize().getWidth() - pageTextWidth1) -10 ;

                    PdfContentByte cb2 = writer.getDirectContent();
                    ColumnText.showTextAligned(cb2, Element.ALIGN_LEFT,
                            new Phrase(headerText, footerFont), startX1, textY, 0);
//                    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.lineTo(pageWidth, yPos);
            canvas.stroke();
        }
    }
}