package com.qmth.boot.tools.pdf;

import com.lowagie.text.Image;
import com.lowagie.text.pdf.*;
import com.qmth.boot.tools.freemarker.FreemarkerUtil;
import com.qmth.boot.tools.io.IOUtils;
import com.qmth.boot.tools.models.ByteArray;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

/**
 * PDF表单填充工具
 */
public class PdfFormUtil {

    private static BaseFont baseFont;

    private static void fill(PdfReader reader, OutputStream ous, Object params) throws IOException {
        // 加载默认字体
        if (baseFont == null) {
            baseFont = BaseFont.createFont("simsun.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, true,
                    ByteArray.fromResource("font/simsun.ttf").value(), null);
        }
        PdfStamper stamp = new PdfStamper(reader, ous);
        AcroFields form = stamp.getAcroFields();
        // 遍历表单字段
        for (String key : form.getAllFields().keySet()) {
            String param = getParam(key, params);
            // 替换图片变量区内容
            if (form.getFieldType(key) == 1) {
                try {
                    Image image = Image.getInstance(ByteArray.fromBase64(param).value());
                    int size = form.getFieldItem(key) != null ? form.getFieldItem(key).size() : 0;
                    for (int i = 0; i < size; i++) {
                        PushbuttonField field = form.getNewPushbuttonFromField(key, i);
                        field.setLayout(PushbuttonField.LAYOUT_ICON_ONLY);
                        field.setProportionalIcon(true);
                        field.setImage(image);
                        form.replacePushbuttonField(key, field.getField(), i);
                    }
                } catch (Exception exception) {
                    continue;
                }
            }
            // 替换文字变量区内容
            else {
                form.setFieldProperty(key, "textfont", baseFont, null);
                form.setField(key, param);
            }
        }
        stamp.setFormFlattening(true);
        stamp.close();
        reader.close();
        IOUtils.closeQuietly(ous);
    }

    private static String getParam(String key, Object params) {
        // 使用FreeMarker表达式获取变量值
        if (key.startsWith("${")) {
            return FreemarkerUtil.getValue(key, params, "");
        }
        // 非ft表达式，且数据对象为map时通过key获取变量值
        else if (params instanceof Map) {
            Object param = ((Map) params).get(key);
            return param != null ? param.toString() : "";
        }
        // 默认返回
        else {
            return "";
        }
    }

    /**
     * <p>PDF表单填充，生成新的PDF文件</p>
     * <p>图片需要转成base64字符串放置到数据对象中</p>
     *
     * @param ins    PDF模版文件输入流
     * @param ous    新PDF文件输出流
     * @param params 数据对象
     * @throws IOException
     */
    public static void fill(InputStream ins, OutputStream ous, Object params) throws IOException {
        fill(new PdfReader(ins), ous, params);
    }

    /**
     * <p>PDF表单填充，生成新的PDF文件</p>
     * <p>图片需要转成base64字符串放置到数据对象中</p>
     *
     * @param data   PDF模版文件内容
     * @param ous    新PDF文件输出流
     * @param params 数据对象
     * @throws IOException
     */
    public static void fill(byte[] data, OutputStream ous, Object params) throws IOException {
        fill(new PdfReader(data), ous, params);
    }
}
