package com.qmth.paper.library.common.util.pdf;

import cn.hutool.core.io.resource.ResourceUtil;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.EncryptionConstants;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.WriterProperties;
import com.itextpdf.layout.Document;
import com.qmth.boot.core.exception.StatusException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

public class ItextPdfUtil {

    private static final Logger log = LoggerFactory.getLogger(ItextPdfUtil.class);

    /*********************
     * 默认页面72像素/英寸
     */
    public static int ItextPagePix = 72;
    // 一英寸等于25.4毫米
    public final static double InchMillimeter = 25.4;

    /********************
     * 获取pdf默认字体
     */
    public static PdfFont getPdfFont() {
        try {
            return PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H", false);
        } catch (Exception e) {
            return null;
        }
    }

    /**********************
     * 获取宋体字体，如无法获取，获取默认字体
     */
    public static PdfFont getPdfFontSTSong() {
        try {
            InputStream in = ResourceUtil.getStream("font" + File.separator + "STSONG.TTF");
            return PdfFontFactory.createFont(getByte(in), PdfEncodings.IDENTITY_H, false);
        } catch (Exception e) {
            log.error(e.getMessage());
            return getPdfFont();
        }
    }

    public static byte[] getByte(InputStream in) {
        InputStream stream = ResourceUtil.getStream("font" + File.separator + "STSONG.TTF");
        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
        byte[] buff = new byte[100];
        int rc = 0;
        try {
            while ((rc = stream.read(buff, 0, 100)) > 0) {
                swapStream.write(buff, 0, rc);
            }
        } catch (IOException e) {
            throw new StatusException("读取文件异常");
        }
        return swapStream.toByteArray();
    }

    public static Document createPdf(File file, PageSize pageSize, String passwd) {
        PdfDocument pdfDoc = null;
        Document doc = null;
        try {

            if (StringUtils.isNotEmpty(passwd))
                pdfDoc = new PdfDocument(new PdfWriter(file.getPath(),
                        new WriterProperties().setStandardEncryption(null, passwd.getBytes(),
                                EncryptionConstants.ALLOW_PRINTING,
                                EncryptionConstants.ENCRYPTION_AES_128 | EncryptionConstants.DO_NOT_ENCRYPT_METADATA)));
            else
                pdfDoc = new PdfDocument(new PdfWriter(file.getPath()));
            doc = new Document(pdfDoc, pageSize);
            return doc;
        } catch (Exception e) {
            throw new StatusException("无法创建临时文件！");
        }
    }

    /**********************
     * 创建A4，自带加密
     */
    public static Document createPdf(File file, String passwd) {
        return createPdf(file, PageSize.A4, passwd);
    }

    /**********************
     * 创建A4，自带加密
     */
    public static Document createPdf(File file, PageSize pageSize) {
        return createPdf(file, pageSize, null);
    }

    public static Document createPdf(File file) {
        return createPdf(file, PageSize.A4, null);
    }

    public static void closePdf(Document doc) {
        if (doc != null) {
            try {

                doc.flush();
                doc.close();
            } catch (Exception ex) {
                log.error(ex.getMessage());
            }
            try {
                doc.getPdfDocument().close();
            } catch (Exception ex) {
                log.error(ex.getMessage());
            }
            doc = null;

        }
    }

    /*********************
     * 获取纸张大小
     * 
     * @param width  宽度 单位毫米
     * @param height 高度 单位毫米 72像素/英寸=28.346像素/厘米 A4:595, 842 A3:842, 1190
     */
    public static PageSize getPageSizeByMillimeter(int width, int height) {
        return new PageSize(getPixByMillimeter(width), getPixByMillimeter(height));

    }

    /****************
     * 根据毫米返回itext的像素
     */
    public static int getPixByMillimeter(int millimeter) {
        return (int) Math.round(millimeter / InchMillimeter * ItextPagePix);
    }

    /****************
     * 根据itext像素返回的毫米
     */
    public static int getMillimeterByPix(int pix) {
        return (int) Math.round((double) pix / ItextPagePix * InchMillimeter);
    }
}
