package yem.wm.cm.htqs.form;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.internal.util.file.ByteArrayOutputStream;
import kd.bos.bill.AbstractBillPlugIn;
import kd.bos.bill.OperationStatus;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.serialization.SerializationUtils;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.entity.datamodel.ListSelectedRow;
import kd.bos.entity.filter.FilterBuilder;
import kd.bos.entity.filter.FilterCondition;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.fileservice.FileService;
import kd.bos.fileservice.FileServiceFactory;
import kd.bos.form.CloseCallBack;
import kd.bos.form.FormShowParameter;
import kd.bos.form.IPageCache;
import kd.bos.form.ShowType;
import kd.bos.form.control.EntryGrid;
import kd.bos.form.control.FilterGrid;
import kd.bos.form.control.events.ItemClickEvent;
import kd.bos.form.events.ClosedCallBackEvent;
import kd.bos.form.field.events.AfterF7SelectEvent;
import kd.bos.form.field.events.AfterF7SelectListener;
import kd.bos.ksql.util.StringUtil;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.print.api.PrintTask;
import kd.bos.print.api.PrintWork;
import kd.bos.print.core.service.PrtAttach;
import kd.bos.print.service.BosPrintServiceHelper;
import kd.bos.servicehelper.AttachmentServiceHelper;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.servicehelper.user.UserConfigServiceHelper;
import kd.sdk.plugin.Plugin;
import org.apache.commons.lang3.StringUtils;
import yem.base.common.utils.YEM;
import yem.wm.cm.htqs.util.DoPrint;

import javax.json.Json;
import javax.json.JsonString;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 单据操作插件
 */
public class SignOperation extends AbstractBillPlugIn implements AfterF7SelectListener {

    private Long entryPk = 0L;

    private String orgAchmentType = "";


    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
        addItemClickListeners(new String[]{"yem_advcont"});
    }

    @Override
    public void afterF7Select(AfterF7SelectEvent e) {
        // 获取选中行
        ListSelectedRow selectRowList = e.getListSelectedRow();
        // 获取选中分录行主键
        this.entryPk = (Long) selectRowList.getEntryPrimaryKeyValue();
    }

    @Override
    public void itemClick(ItemClickEvent evt) {
        super.itemClick(evt);
        String itemKey = evt.getItemKey();
        switch (itemKey) {
            case "yem_sign":
                this.signContract();
                break;
            default:
                break;
        }
    }


    /**
     * 查询此单据的签署方式
     */
    private void signContract() {
        DynamicObject data = this.getView().getModel().getDataEntity(true);
        String name = data.getDataEntityType().getName();
        String setting = UserConfigServiceHelper.getSetting(RequestContext.get().getCurrUserId(),
                name + "_printsetting");
        if (setting == null) {
            this.getView().showMessage("请先设置默认打印模板！！！");
            return;
        }
        String billStatus = data.getString("billstatus");
        if ("A".equals(billStatus)) {
            this.getView().showErrorNotification("暂存状态不可用");
            return;
        }

        String properties = "yem_signaturemethod,yem_checkcondition_tag";
        //查找所有匹配的签署规则。
        DynamicObject[] signRules =
                BusinessDataServiceHelper.load("yem_cm_signaddress", properties, new QFilter[]{});

        String method = "";//A手动签署  B自动签署

        for (DynamicObject signRule : signRules) {
            String checkcondition_tag = signRule.getString("yem_checkcondition_tag");
            if (checkcondition_tag == null || checkcondition_tag.isEmpty()) {
                continue;
            }
            Long pkValue = (Long) data.getPkValue();
            JSONObject condition = JSON.parseObject(checkcondition_tag);
            String yemFiltergridap = condition.getString("yem_filtergridap");
            List<QFilter> qFilters = new ArrayList<>();
            qFilters.add(new QFilter("ID", QCP.equals, pkValue));
            FilterCondition filterCondition = SerializationUtils.fromJsonString(yemFiltergridap, FilterCondition.class);
            if (filterCondition != null) {
                FilterBuilder fBuilder = new FilterBuilder(this.getView().getModel().getDataEntityType(), filterCondition);
                fBuilder.buildFilter();
                qFilters.addAll(fBuilder.getQFilters());
            }

            DynamicObject load = BusinessDataServiceHelper.
                    loadSingle("yem_cm_contractsign", "billno", qFilters.toArray(new QFilter[0]));
            if (load == null) {
                continue;
            }
            method = signRule.getString("yem_signaturemethod");
            break;
        }
        if (method.isEmpty()) {
            this.getView().showMessage("无匹配签署方案");
        }
        signSelectFiles(method);
    }

    private void signSelectFiles(String method) {
        // 获取单据体控件
        EntryGrid entryGrid = this.getControl("yem_attachmentdetail");
        // 获取选中行，数组为行号，从0开始
        int[] selectRows = entryGrid.getSelectRows();
        if (selectRows.length == 0) {
            this.getView().showMessage("请选中要签署的附件");
            return;
        }

        DynamicObject form = this.getView().getModel().getDataEntity();
        DynamicObjectCollection Entry = this.getView().getModel().getEntryEntity("yem_attachmentdetail");
        String yemSigning = form.getString("yem_signing");

        StringBuilder sb = new StringBuilder();
        for (int selectRow : selectRows) {
            DynamicObject entryEntity = Entry.get(selectRow);
            DynamicObject attachmenttype = entryEntity.getDynamicObject("yem_attachmenttype");
            String name = attachmenttype.getString("name");
            if (!("合同".equals(name) || "单签".equals(name))) {//如果不是合同类型或单签类型的附件则不能签署
                sb.append("第").append(selectRow + 1).append("条附件签署失败!  注意：只能签署合同或单签类型附件！！！");
            }
            if ("合同".equals(name) && "B".equals(yemSigning)) {//如果要签署合同文件的话，签订方向必须为我方先签
                sb.append("第").append(selectRow + 1).append("条附件签署失败!  注意：当对方先签时，不能进行签署操作！！！");
            }
            if ("单签".equals(name) && "A".equals(yemSigning)) {//如果要签署单签文件的话，签订方向必须为对方先签
                sb.append("第").append(selectRow + 1).append("条附件签署失败!  注意：只有当对方先签的情况下才可以进行双签操作！！！");
            } else {
                //存储需要操作的附件行数
                IPageCache pageCache = this.getView().getPageCache();
                String jsonSelect = JSON.toJSONString(selectRow);
                pageCache.put("selectRow", jsonSelect);
                if ("B".equals(method)) {//B手动签署  A自动签署
                    FormShowParameter showParameter = new FormShowParameter();// 创建弹出动态表单页面对象
                    showParameter.setFormId("yem_cm_manualsignpage");// 设置弹出页面的标识
                    showParameter.setStatus(OperationStatus.ADDNEW);// 状态

                    String formId = this.getView().getFormShowParameter().getFormId();
                    showParameter.setCloseCallBack(new CloseCallBack(this, formId));// 设置页面关闭回调方法
                    showParameter.getOpenStyle().setShowType(ShowType.MainNewTabPage);// 设置弹出页面打开方式
                    this.getView().showForm(showParameter);    // 打开动态表单
                } else {
                    //自动签署直接打印文件
                    printContract();
                }
                this.getView().invokeOperation("save");
            }
            if (sb.length() > 0) {
                sb.append(System.getProperty("line.separator"));//换行
            }
        }
        if (sb.length() > 0) {
            this.getView().showErrorNotification("签署失败!" + System.getProperty("line.separator") + sb);
        } else {
            this.getView().showSuccessNotification("签署成功!");
        }
    }

    private void printContract() {
        IDataModel model = this.getView().getModel();
        DynamicObject data = model.getDataEntity(true);

        String s = this.getView().getPageCache().get("selectRow");
        Integer selectRow = JSON.parseObject(s, Integer.class);

        DynamicObject entryEntity = this.getView().getModel().getEntryEntity("yem_attachmentdetail").get(selectRow);
        DynamicObject attachmenttype = entryEntity.getDynamicObject("yem_attachmenttype");
        String attTypeName = attachmenttype.getString("name");
        String type = "";
        // 根据选中附件类型判断签署后需要生成的附件类型
        if ("合同".equals(attTypeName)) {
            type = "单签";
        } else if ("单签".equals(attTypeName)) {
            type = "双签";
        }

        //获取打印模板名称
        String name = data.getDataEntityType().getName();
        String tplId = "";
        String printLang = "";
        String setting = UserConfigServiceHelper.getSetting(RequestContext.get().getCurrUserId(),
                name + "_printsetting");

        JSONObject fromJsonString = SerializationUtils.fromJsonString(setting, JSONObject.class);
        if (fromJsonString != null) {
            tplId = fromJsonString.getString("templateid");
            printLang = fromJsonString.getString("printlang");
        }

        //根据打印模板id获取打印模板名称
        DynamicObject printtpl = BusinessDataServiceHelper.
                loadSingle("bos_manageprinttpl", new QFilter[]{new QFilter("printtplid", QCP.equals, tplId)});
        String settingName = printtpl.getString("name");

        //开始打印
        if (!YEM.isEmpty(tplId)) {
            ArrayList<Object> pkIds = new ArrayList<>();
            pkIds.add(data.getPkValue());
            // 打印任务
            ArrayList<PrintTask> taskList = new ArrayList<>();
            PrintTask printTask = new PrintTask();
            printTask.setTplId(tplId);// 打印模板的id
            printTask.setPkIds(pkIds);
            printTask.setPrintType("billForm");// 打印对象的类型，是单据（billForm),报表（report)，还是动态表单(dynamic)
            printTask.setFormId(name);
            taskList.add(printTask);
            // 打印作业
            PrintWork printWork = new PrintWork();
            printWork.setPrintLang(YEM.isEmpty(printLang) ? "zh_CN" : printLang);
            printWork.setExpType("pdf");
            printWork.setTaskList(taskList);
            // 生成打印模板生成的pdf文件
            PrtAttach doPrint = BosPrintServiceHelper.doPrint(printWork);
            List<PrtAttach.AttachDetail> attachDetails = doPrint.getAttachDetail();
            PrtAttach.AttachDetail attachDetail = attachDetails.get(0);
            // 将文件保存到附件
            List<Map<String, Object>> atts = new ArrayList<Map<String, Object>>();
            //构建附件面板信息
            Map<String, Object> map = DoPrint.createAttInfo(attachDetail, data.getString("billno"), settingName);
            atts.add(map);
            // 上传附件到采购订单的附件面板中
            AttachmentServiceHelper.upload(name, data.getPkValue(), "attachmentpanel", atts);

            String fileUid = (String) map.get("uid");


            DoPrint.uploadFiles(data, name, fileUid, tplId, type);

        }

    }


    @Override
    public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {
        super.closedCallBack(closedCallBackEvent);
        printContract();
        this.getView().invokeOperation("refresh");
    }

    private void forbiddenSet(Boolean forbidden) {
        //锁定签署按钮
//		this.getView().setEnable(forbidden,"yem_sign");
    }

    @Override
    public void afterCreateNewData(EventObject e) {
        super.afterCreateNewData(e);
        forbiddenSet(false);
    }

    @Override
    public void afterLoadData(EventObject e) {
        super.afterLoadData(e);
        forbiddenSet(false);
    }

    @Override
    public void afterCopyData(EventObject e) {
        super.afterCopyData(e);
        forbiddenSet(false);
    }

}