package com.yem.wm.es.salesorder.op;

import com.yem.wm.es.encasement.util.AttachmentUtil;
import com.yem.wm.utils.ContactSignUtils;
import com.yem.wm.utils.YEM;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.entity.AppInfo;
import kd.bos.entity.AppMetadataCache;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.PreparePropertysEventArgs;
import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
import kd.bos.exception.KDBizException;
import kd.bos.fileservice.FileServiceFactory;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.AttachmentDto;
import kd.bos.servicehelper.AttachmentServiceHelper;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.url.UrlService;
import org.jetbrains.annotations.NotNull;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;

/**
 * @Description: 衣总签名带到Word文件ensign书签位置处
 * @Date: 2024/8/19 10:34
 * @Created: by ZZSLL
 */

public class SalesOrderAutoSignOp extends AbstractOperationServicePlugIn {

    @Override
    public void onPreparePropertys(PreparePropertysEventArgs e) {
        super.onPreparePropertys(e);
        List<String> fieldKeys = e.getFieldKeys();
        fieldKeys.addAll(this.billEntityType.getAllFields().keySet());
    }

    @Override
    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
        super.beginOperationTransaction(e);
        DynamicObject[] entities = e.getDataEntities();

        // Word中的书签名称
        final String bookmark = "ensign";
        // 修改Word后上传的附件面板
        final String UPLOAD_ATTACHMENT_KEY = "yem_approval";

        for (DynamicObject dynamicObject : entities) {
            String formId = dynamicObject.getDataEntityType().getName();
            long pkId = dynamicObject.getLong("id");

            // 获取衣晓明签字
            DynamicObject user = BusinessDataServiceHelper.loadSingle("bos_user", new QFilter[]{new QFilter("number", "=", "10437")});
            String imageId = user.getString("yem_signature");
            if (YEM.isEmpty(imageId)) {
                throw new KDBizException("获取工号 10437 的用户签章失败，请检查是否上传签章！！");
            }

            // 下载签字图片文件
            String imageUrl = UrlService.getImageFullUrl(imageId);
            imageUrl = imageUrl + "?access_token=" + RequestContext.get().getGlobalSessionId();
            InputStream imageIn;
            ByteArrayOutputStream buffer;
            try {
                URL url = new URL(imageUrl);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");
                imageIn = connection.getInputStream();
                // 图片数据缓存，InputStream多次使用
                buffer = new ByteArrayOutputStream();
                int nRead;
                byte[] data = new byte[1024];
                while ((nRead = imageIn.read(data, 0, data.length)) != -1) {
                    buffer.write(data, 0, nRead);
                }
                buffer.flush();

                connection.disconnect();
            } catch (IOException ex) {
                throw new KDBizException("下载工号 10437 的用户签章失败！！");
            }

            byte[] imageData = buffer.toByteArray();

            // 清空上传的附件面板
            List<Map<String, Object>> beforeUpload = AttachmentServiceHelper.getAttachments(formId, pkId, UPLOAD_ATTACHMENT_KEY);
            for (Map<String, Object> map : beforeUpload) {
                AttachmentServiceHelper.remove(formId, pkId, map.get("uid"));
            }

            final String DOWNLOAD_ATTACHMENT_KEY = "attachmentpanel";
            List<Map<String, Object>> attachments = AttachmentServiceHelper.getAttachments(formId, pkId, DOWNLOAD_ATTACHMENT_KEY);

            AppInfo appInfo = AppMetadataCache.getAppInfo("yem_es");
            String appId = appInfo.getId();

            for (Map<String, Object> attachment : attachments) {
                // 获取Word附件
                AttachmentDto attDao = AttachmentServiceHelper.getAttachmentInfoByAttPk(attachment.get("attPkId"));
                String fileUrl = attDao.getResourcePath();
                String filename = attDao.getFilename();
                validatorFileExtension(filename);
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                FileServiceFactory.getAttachmentFileService().download(fileUrl, out, null);
                InputStream in = new ByteArrayInputStream(out.toByteArray());
                InputStream validatorStream = new ByteArrayInputStream(out.toByteArray());

                // 获取书签
                List<CTBookmark> bookMarks = ContactSignUtils.getFileBookMarks(validatorStream);
                validatorSignAble(bookMarks, bookmark, filename);

                File file;
                try {

                    ByteArrayInputStream stream = new ByteArrayInputStream(imageData);

                    // 书签位置替换为图片（书签不会删除）
                    file = ContactSignUtils.replaceBookmarkWithImage(in, stream, filename, bookmark);
                    AttachmentUtil.uploadAttachment(appId, formId, String.valueOf(pkId), UPLOAD_ATTACHMENT_KEY, file.getName(), file.getPath());
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
        }
    }

    /**
     * 检验是否是Word文件
     * @param filename
     */
    private void validatorFileExtension(String filename) {
        if (!filename.endsWith(".docx") && !filename.endsWith(".doc")) {
            throw new KDBizException("文件 " + filename + " 扩展名不正确，请上传 .doc 或 .docx 文件！！");
        }
    }

    /**
     * 校验Word是否有书签
     *
     * @param bookMarks
     * @param name
     * @param filename
     * @return
     */
    private void validatorSignAble(List<CTBookmark> bookMarks, @NotNull String name, String filename) {
        boolean pass = false;
        for (CTBookmark bookMark : bookMarks) {
            String bookMarkName = bookMark.getName();
            if (name.equals(bookMarkName)) {
                pass = true;
                break;
            }
        }
        if (!pass) {
            throw new KDBizException("未在文件 " + filename + " 中找到书签： " + name + "请上传添加书签后的Word文件！！");
        }
    }
}
