package dev.bytevibe.hyperpoint;

import javafx.scene.image.WritableImage;
import javafx.scene.image.PixelReader;
import javafx.scene.layout.Pane;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfWriter;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 导出工具类，用于导出页面为图片和导出幻灯片为PDF
 */
public class ExportUtil {

    /**
     * 导出页面为图片（PNG或JPG）
     *
     * @param pane 要导出的页面Pane
     * @param file 输出文件
     * @param format 图片格式 "png" 或 "jpg"
     * @throws IOException 如果导出失败
     */
    public static void exportPageAsImage(Pane pane, File file, String format) throws IOException {
        // 获取Pane的宽度和高度
        double width = pane.getWidth();
        double height = pane.getHeight();

        // 如果宽度或高度无效，尝试使用布局宽度/高度
        if (width <= 0 || height <= 0) {
            width = pane.getLayoutBounds().getWidth();
            height = pane.getLayoutBounds().getHeight();
        }

        // 如果仍然无效，使用固定的默认大小
        if (width <= 0) {
            width = 1024;
        }
        if (height <= 0) {
            height = 768;
        }

        // 创建WritableImage用于捕获页面内容
        WritableImage writableImage = new WritableImage((int) width, (int) height);
        pane.snapshot(null, writableImage);

        // 转换为BufferedImage
        BufferedImage bufferedImage = convertFXImageToBufferedImage(writableImage);

        // 写入文件
        String formatName = format.equalsIgnoreCase("jpg") ? "jpg" : "png";
        if (!ImageIO.write(bufferedImage, formatName, file)) {
            throw new IOException("无法写入" + formatName + "文件");
        }
    }

    /**
     * 将JavaFX WritableImage转换为BufferedImage
     */
    private static BufferedImage convertFXImageToBufferedImage(WritableImage fxImage) {
        int width = (int) fxImage.getWidth();
        int height = (int) fxImage.getHeight();
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        PixelReader pixelReader = fxImage.getPixelReader();
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int argb = pixelReader.getArgb(x, y);
                bufferedImage.setRGB(x, y, argb);
            }
        }

        return bufferedImage;
    }

    /**
     * 导出整个幻灯片为PDF
     *
     * @param slide 要导出的幻灯片
     * @param file 输出PDF文件
     * @throws Exception 如果导出失败
     */
    public static void exportSlideToPDF(Slide slide, File file) throws Exception {
        if (slide == null || slide.getPages().isEmpty()) {
            throw new IOException("幻灯片没有页面");
        }

        // 创建PDF文档
        Document document = new Document(PageSize.A4);
        PdfWriter.getInstance(document, new FileOutputStream(file));
        document.open();

        // 为每一页添加内容
        for (SlidePage page : slide.getPages()) {
            // 添加页面标题
            Paragraph title = new Paragraph(page.getTitle(), new com.itextpdf.text.Font(
                    com.itextpdf.text.Font.FontFamily.HELVETICA, 16, com.itextpdf.text.Font.BOLD));
            title.setSpacingAfter(10);
            document.add(title);

            // 添加页面内容（如果有的话）
            if (page.getContent() != null && !page.getContent().isEmpty()) {
                Paragraph content = new Paragraph(page.getContent(), new com.itextpdf.text.Font(
                        com.itextpdf.text.Font.FontFamily.HELVETICA, 12));
                content.setSpacingAfter(10);
                document.add(content);
            }

            // 添加对象列表
            addObjectsToDocument(document, page.getPageContent());

            // 每页之间添加分页符
            document.newPage();
        }

        document.close();
    }

    /**
     * 将页面内容的对象添加到PDF文档
     */
    private static void addObjectsToDocument(Document document, PageContent pageContent) throws DocumentException {
        for (DrawableObject obj : pageContent.getDrawableObjects()) {
            if (obj instanceof TextObject) {
                addTextObjectToDocument(document, (TextObject) obj);
            } else if (obj instanceof ShapeObject) {
                addShapeObjectToDocument(document, (ShapeObject) obj);
            } else if (obj instanceof ImageObject) {
                addImageObjectToDocument(document, (ImageObject) obj);
            }
        }
    }

    /**
     * 添加文本对象到PDF
     */
    private static void addTextObjectToDocument(Document document, TextObject textObj) throws DocumentException {
        float fontSize = (float) textObj.getFontSize();
        int fontStyle = com.itextpdf.text.Font.NORMAL;

        if (textObj.getFontStyle().contains("BOLD")) {
            fontStyle |= com.itextpdf.text.Font.BOLD;
        }
        if (textObj.getFontStyle().contains("ITALIC")) {
            fontStyle |= com.itextpdf.text.Font.ITALIC;
        }

        com.itextpdf.text.Font font = new com.itextpdf.text.Font(
                com.itextpdf.text.Font.FontFamily.HELVETICA, fontSize, fontStyle);

        Paragraph paragraph = new Paragraph(textObj.getText(), font);
        paragraph.setSpacingAfter(5);
        document.add(paragraph);
    }

    /**
     * 添加形状对象到PDF
     */
    private static void addShapeObjectToDocument(Document document, ShapeObject shapeObj) throws DocumentException {
        String shapeInfo = "图形: " + shapeObj.getShapeType().name() +
                         " (位置: " + (int)shapeObj.getX() + ", " + (int)shapeObj.getY() +
                         " 大小: " + (int)shapeObj.getWidth() + "x" + (int)shapeObj.getHeight() + ")";

        Paragraph paragraph = new Paragraph(shapeInfo, new com.itextpdf.text.Font(
                com.itextpdf.text.Font.FontFamily.HELVETICA, 10));
        paragraph.setSpacingAfter(5);
        document.add(paragraph);
    }

    /**
     * 添加图片对象到PDF
     */
    private static void addImageObjectToDocument(Document document, ImageObject imageObj) throws DocumentException {
        String imagePath = imageObj.getImagePath();
        if (imagePath != null && !imagePath.isEmpty()) {
            try {
                // 检查文件是否存在
                File imageFile = new File(imagePath);
                if (imageFile.exists()) {
                    Image img = Image.getInstance(imagePath);
                    // 限制图片大小
                    float maxWidth = document.getPageSize().getWidth() - 40;
                    float maxHeight = document.getPageSize().getHeight() / 3;
                    if (img.getWidth() > maxWidth) {
                        img.scaleToFit(maxWidth, maxHeight);
                    }
                    img.setSpacingAfter(10);
                    document.add(img);
                } else {
                    Paragraph para = new Paragraph("[图片不存在: " + imagePath + "]",
                            new com.itextpdf.text.Font(com.itextpdf.text.Font.FontFamily.HELVETICA, 10));
                    para.setSpacingAfter(5);
                    document.add(para);
                }
            } catch (Exception e) {
                Paragraph para = new Paragraph("[无法加载图片: " + e.getMessage() + "]",
                        new com.itextpdf.text.Font(com.itextpdf.text.Font.FontFamily.HELVETICA, 10));
                para.setSpacingAfter(5);
                document.add(para);
            }
        }
    }
}

