package com.yem.em.task;

import com.yem.em.utils.AtlasUtils;
import com.yem.wm.utils.AttachmentUtil;
import com.yem.wm.utils.DynamicObjectUtil;
import com.yem.wm.utils.YEM;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.exception.KDException;
import kd.bos.fileservice.FileServiceFactory;
import kd.bos.orm.query.QFilter;
import kd.bos.schedule.executor.AbstractTask;
import kd.bos.servicehelper.AttachmentServiceHelper;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

import static com.yem.em.task.MatchingPLMChangeUpdateTaskEdit.*;
import static com.yem.em.utils.AtlasUtils.seelctDyn;
import static com.yem.rf.utils.RFUtils.getBaseQFilter;

/**
 * @Description: 1、如《PLM变更单》分录【替换关系】=【相互替换】【新替换旧】【互不替换】,分录【启用停用状态】=‘停用’，并且【替换件启用停用状态】=‘启用’，更新当前行【执行状态】为【完成】、【完成时间】默认当前时间，并生成替换关系，记录替换关系id以及行id
 * <p>
 * 2、如《PLM变更单》分录【替换关系】=【新增】,分录【替换件启用停用状态】=‘启用’，更新当前行【执行状态】为【完成】、【完成时间】默认当前时间，并生成替换关系，记录替换关系id以及行id
 * <p>
 * 3、如《PLM变更单》分录【替换关系】=【删除】,分录【启用停用状态】=‘停用’，更新当前行【执行状态】为【完成】、【完成时间】默认当前时间，并生成替换关系，记录替换关系id以及行id
 * @Date: 2024/8/29 15:38
 * @Created: by ZZSLL
 */

public class GenerateReplaceRelationshipTaskEdit extends AbstractTask {

    private final static Logger logger = LoggerFactory.getLogger(GenerateReplaceRelationshipTaskEdit.class);

    @Override
    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {

        DynamicObject[] plms = queryPLMChange();

        for (DynamicObject plmObj : plms) {
            DynamicObjectCollection collection = plmObj.getDynamicObjectCollection("yem_change_detail");
            DynamicObjectCollection situation_replace = new DynamicObjectCollection();
            DynamicObjectCollection situation_add = new DynamicObjectCollection();
            DynamicObjectCollection situation_delete = new DynamicObjectCollection();

            for (DynamicObject plm : collection) {
                String enablesta = plm.getString("yem_enablesta");//替换件停用启用状态
                String enablestatus_before = plm.getString("yem_enablestatus_before");//停用启用状态
                String isgenfnish = plm.getString("yem_isgenfnish");
                String exchangetype = plm.getString("yem_exchangetype");
                String invokstatus = plm.getString("yem_invokstatus");//执行状态
                String invoktime = plm.getString("yem_invoktime");//执行时间
                if ("B".equals(invokstatus) && YEM.isNotEmpty(invoktime) && YEM.isNotEmpty(exchangetype)) {

                    //【替换关系】=【相互替换】【新替换旧】【互不替换】 && 【启用停用状态】=‘停用’ && 【替换件启用停用状态】=‘启用’ && 执行状态 != 已完成
                    if ("A-B-C".contains(exchangetype) && "A".equals(enablesta) && "B".equals(enablestatus_before) && !"B".equals(isgenfnish)) {
                        situation_replace.add(plm);
                    }

                    // 【替换关系】=【新增】 && 【替换件启用停用状态】=‘启用’
                    if ("D".equals(exchangetype) && "A".equals(enablesta) && !"B".equals(isgenfnish)) {
                        situation_add.add(plm);
                    }
                    // 【替换关系】=【删除】 && 分录【启用停用状态】=‘停用’
                    if ("E".equals(exchangetype) && "B".equals(enablestatus_before) && !"B".equals(isgenfnish)) {
                        situation_delete.add(plm);
                    }
                }

            }
            generateReplaceRelation(plmObj, situation_replace);
            generateReplaceRelation(plmObj, situation_add);
            generateReplaceRelation(plmObj, situation_delete);
        }
    }

    /**
     * 生成替换关系，更新完成时间、状态
     *
     * @param plmObj
     * @param enabled
     */
    private void generateReplaceRelation(DynamicObject plmObj, DynamicObjectCollection enabled) {
        DynamicObjectCollection collection = plmObj.getDynamicObjectCollection("yem_change_detail");
        ArrayList<DynamicObject> remove = Lists.newArrayList();
        // 更新是否资源、是否总成
        for (DynamicObject plm : enabled) {

            String exchangetype = plm.getString("yem_exchangetype");
            String parentno;
            if ("D".equals(exchangetype)) {//新增
                parentno = plm.getString("yem_parent_now");
            } else {
                parentno = plm.getString("yem_textfield");
            }
            DynamicObject assatlasdet = seelctDyn("yem_em_assatlasdet", "number", parentno);//父项编码
            plm.set("yem_isassy", false);
            plm.set("yem_isresource", false);
            if (assatlasdet != null) {
                plm.set("yem_isassy", true);
            }
            logger.info("是否总成：{}，{}", parentno, assatlasdet != null);
            DynamicObject basemodelib = seelctDyn("yem_bd_basemodelib", "number", parentno);
            if (basemodelib != null) {
                plm.set("yem_isresource", true);
            }
            logger.info("是否资源：{}，{}", parentno, basemodelib != null);

            if (!plm.getBoolean("yem_isassy") && !plm.getBoolean("yem_isresource")) {
                remove.add(plm);
            }
        }
        collection.removeAll(remove);
        // 替换关系生成成功之后更新完成时间、状态
        Map<Long, DynamicObject> successMap = new HashMap<>();
        DynamicObject bomChange = createBOMChange(plmObj, enabled);
        DynamicObjectCollection entry = bomChange.getDynamicObjectCollection("yem_entryentity");

        for (DynamicObject entryObject : entry) {
            useExistReplace(bomChange, entryObject, successMap);
        }
//        if (!entry.isEmpty()) {
//            DynamicObject replace = null;
//            String billno = plmObj.getString("billno");
//            String gybg_no = plmObj.getString("yem_gybg_no");
//            if (entry.size() == 1) {
//                logger.info("生成替换关系：PLM单号：{}， PLM工艺变更单号：{}，父项编码：{}", billno, gybg_no, entry.get(0).getString("yem_parentno"));
//                logger.info("生成_当前替换关系：{}", entry.get(0).getString("yem_replace"));
//                replace = AtlasUtils.Addreplace(bomChange, entry.get(0), null, "yem_em_replace", "add", "PLM");
//                successMap.put(entry.get(0).getLong("id"), bomChange);
//            } else {
//                for (DynamicObject entryObject : entry) {
//                    int idx = entry.indexOf(entryObject);
//                    if (idx == 0) {
//                        QFilter qFilter = new QFilter("status", "=", "C");
//                        qFilter.and("number", "=", entryObject.getString("yem_parentno"));
//                        DynamicObject[] load = BusinessDataServiceHelper.load("yem_em_replace", selectfields, qFilter.toArray());
//                        if (load.length == 1) {
//                            replace = load[0];
//                            replace = AtlasUtils.Addreplace(bomChange, entry.get(0), replace, "yem_em_replace", "update", "PLM");
//                        } else {
//                            replace = AtlasUtils.Addreplace(bomChange, entry.get(0), null, "yem_em_replace", "add", "PLM");
//                        }
//                        continue;
//                    };
//                    logger.info("更新替换关系：PLM单号：{}， PLM工艺变更单号：{}，父项编码：{}", billno, gybg_no, entryObject.getString("yem_parentno"));
//                    logger.info("更新_替换关系：{}", entryObject.getString("yem_replace"));
//                    replace = AtlasUtils.Addreplace(bomChange, entry.get(0), replace, "yem_em_replace", "update", "PLM");
//                    successMap.put(entryObject.getLong("id"), bomChange);
//                }
//            }
//        }
        List<Long> list = new ArrayList<>();
        for (Map.Entry<Long, DynamicObject> mapEntry : successMap.entrySet()) {
            Long bomChangeEntryId = mapEntry.getKey();
//            DynamicObject bomChangeObj = mapEntry.getValue();
//            DynamicObjectCollection bomChangeEntry = bomChangeObj.getDynamicObjectCollection("yem_entryentity");
//            int idx = 0;
//            for (DynamicObject bom : bomChangeEntry) {
//                if (bomChangeEntryId == bom.getLong("id")) {
//                    idx = bomChangeEntry.indexOf(bom);
//                }
//            }
//            DynamicObject currentEntry = bomChangeEntry.get(idx);
//            Date completetime = currentEntry.getDate("yem_completetime");//完成时间
            for (DynamicObject d : collection) {
                long id = d.getLong("id");
                if (bomChangeEntryId == id) {
                    d.set("yem_isgenfnish", "B");
                }
            }

            for (DynamicObject d : collection) {
                long entryId = d.getLong("id");
                String isgenfnish = d.getString("yem_isgenfnish");
                if ("B".equals(isgenfnish)) {
                    list.add(entryId);
                }
            }
        }

        SaveServiceHelper.save(new DynamicObject[]{plmObj});
        syncImage(plmObj, list);
    }

    /**
     * 查询已存在的替换关系
     *
     * @param bomChange
     * @param bomChangeEntry
     * @param successMap
     * @return
     */
    private void useExistReplace(DynamicObject bomChange, DynamicObject bomChangeEntry, Map<Long, DynamicObject> successMap) {
        QFilter qFilter = new QFilter("status", "=", "C");
        qFilter.and("number", "=", bomChangeEntry.getString("yem_parentno"));
        DynamicObject[] load = BusinessDataServiceHelper.load("yem_em_replace", "id, billno", qFilter.toArray());
        if (load.length > 0) {
            DynamicObject replace = load[0];
            replace = BusinessDataServiceHelper.loadSingle(replace.getPkValue(), replace.getDataEntityType().getName());
            logger.info("使用已有替换关系：{}", replace.getString("number"));
            AtlasUtils.Addreplace(bomChange, bomChangeEntry, replace, "yem_em_replace", "update", "PLM");
            successMap.put(bomChangeEntry.getLong("id"), bomChange);
        } else {
            logger.info("创建新的替换关系：{}", bomChangeEntry.getString("yem_parentno"));
            AtlasUtils.Addreplace(bomChange, bomChangeEntry, null, "yem_em_replace", "add", "PLM");
            successMap.put(bomChangeEntry.getLong("id"), bomChange);
        }
    }

    /**
     * 根据PLM创建BOM，用于生成替换关系
     *
     * @param head
     * @param entries
     * @return
     */
    private DynamicObject createBOMChange(DynamicObject head, DynamicObjectCollection entries) {
        DynamicObject bomchange = BusinessDataServiceHelper.newDynamicObject("yem_em_bomchange");
        bomchange.set("id", head.getLong("id"));
        bomchange.set("createorg", head.getDynamicObject("org"));//创建组织-组织
        bomchange.set("yem_producttype", head.getString("yem_producttype"));//产品分类
        bomchange.set("number", head.getString("billno"));//单据编号
        bomchange.set("yem_date", head.getDate("createtime"));//业务日期-创建时间
        bomchange.set("creator", head.getDynamicObject("creator"));//创建人
        DynamicObjectCollection detail = bomchange.getDynamicObjectCollection("yem_entryentity");
        for (DynamicObject entry : entries) {

            if (!entry.getBoolean("yem_isassy") && !entry.getBoolean("yem_isresource")) {
                continue;
            }

            DynamicObject addNew = detail.addNew();
            addNew.set("id", entry.getLong("id"));

            String exchangetype = entry.getString("yem_exchangetype");

            if (exchangetype.equals("D")) {//新增PLM变更后对应BOM变更前
                addNew.set("yem_parentno", entry.getString("yem_parent_now"));//替换后-父件编码
                addNew.set("yem_parentname", entry.getString("yem_name_newparent"));//替换后-父项名称
                addNew.set("yem_subno", entry.getString("yem_child_now"));//替换后-子件编码
                addNew.set("yem_subname", entry.getString("yem_name_newchild"));//替换后-子件名称
                addNew.set("yem_subenname", entry.getString("yem_englishname"));//替换后-子件英文名称
                addNew.set("yem_qty", entry.getBigDecimal("yem_qty_new"));//替换后-数量
            } else {//否则变更前对应变更前
                addNew.set("yem_parentno", entry.getString("yem_textfield"));//替换前-父件编码
                addNew.set("yem_parentname", entry.getString("yem_name_parent"));//替换前-父项名称
                addNew.set("yem_subno", entry.getString("yem_child_before"));//替换前-子件编码
                addNew.set("yem_subname", entry.getString("yem_name_child"));//替换前-子件名称
                addNew.set("yem_subenname", entry.getString("yem_englishname_before"));//替换前-子件英文名称
                addNew.set("yem_qty", entry.getBigDecimal("yem_qty_before"));//替换前-数量
            }

            addNew.set("yem_enableparno", entry.getString("yem_parent_now"));//替换父件编码-父项编码
            addNew.set("yem_enableparname", entry.getString("yem_name_newparent"));//替换父件名称-父项名称
            addNew.set("yem_enablesubno", entry.getString("yem_child_now"));//替换子件编码-子项编码
            addNew.set("yem_enablesubname", entry.getString("yem_name_newchild"));//替换子件名称
            addNew.set("yem_enablesubenname", entry.getString("yem_englishname"));//替换件英文名称-子件英文名称
            addNew.set("yem_enablesubqty", entry.getBigDecimal("yem_qty_new"));//数量

            addNew.set("yem_enablesta", entry.getString("yem_enablesta"));//启用停用状态
            addNew.set("yem_replace", exchangetype);//替换关系
            addNew.set("yem_enableddate", entry.getDate("yem_starttime"));//启用时间
            addNew.set("yem_downdate", entry.getDate("yem_stoptime"));//停用时间
            addNew.set("yem_completetime", entry.getDate("yem_invoktime"));//执行时间
            addNew.set("yem_remark", entry.getString("yem_remark"));//备注
            addNew.set("yem_isass", entry.getBoolean("yem_isassy"));//是否总成
            addNew.set("yem_isresource", entry.getBoolean("yem_isresource"));//是否资源
        }
        return bomchange;
    }

    /**
     * 同步图片 总成图册明细
     *
     * @param plmObj
     * @param list
     */
    private void syncImage(DynamicObject plmObj, List<Long> list) {
        plmObj = BusinessDataServiceHelper.loadSingle(plmObj.getPkValue(), plmObj.getDynamicObjectType().getName());
        DynamicObjectCollection detail = plmObj.getDynamicObjectCollection("yem_change_detail");
        DynamicObjectCollection pictureentry = plmObj.getDynamicObjectCollection("yem_pictureentry");
        for (Long entryId : list) {
            for (DynamicObject d : detail) {
                long id = d.getLong("id");
                if (id == entryId) {
                    String exchangetype = d.getString("yem_exchangetype");
                    String imageName;
                    if ("D".equals(exchangetype)) {
                        imageName = d.getString("yem_parent_now");
                    } else {
                        imageName = d.getString("yem_textfield");
                    }

                    DynamicObject assAtlas = queryMatchAssemblyAtlasDetails(plmObj, d);
                    if (assAtlas == null) continue;
                    List<DynamicObject> imageInfo = getImageInfo(pictureentry, imageName);
                    List<String> successMap = new ArrayList<>();
                    for (DynamicObject image : imageInfo) {
                        String suyntype = image.getString("yem_suyntype");
                        if ("B".equals(suyntype)) continue;
                        String picturename = image.getString("yem_picturename");
                        int idx = picturename.lastIndexOf(".");
                        String partno = picturename.substring(0, idx);
                        String pictureid = image.getString("yem_pictureid");
                        Date breakpointtime = getBreakPointTime(detail, partno);

                        DynamicObject attachment = AttachmentServiceHelper.getAttCreatorByUID(pictureid);
                        if (YEM.isEmpty(attachment)) {
                            continue;
                        }
                        String url = attachment.getString("ffileid");
                        String fattachmentsize = attachment.getString("fattachmentsize");
                        if (YEM.isEmpty(fattachmentsize) || Long.parseLong(fattachmentsize) == 0) {
                            logger.error("错误的文件！！");
                            continue;
                        }
                        DynamicObject afterUpload = AttachmentUtil.uploadAttachmentPanel(assAtlas.getDataEntityType().getName(), assAtlas.getPkValue(), "yem_attachmentpanelap", picturename, url);
                        if (afterUpload != null) {
                            // 更新分录
                            afterUpload.set("fattachmentsize", fattachmentsize);
                            SaveServiceHelper.save(new DynamicObject[]{afterUpload});
                            DynamicObjectCollection attach_detail = assAtlas.getDynamicObjectCollection("yem_attdetail");
                            DynamicObject aNew = attach_detail.addNew();
                            String fileaddress = FileServiceFactory.getAttachmentFileService().getFileServiceExt().getRealPath(afterUpload.getString("ffileid"));
                            aNew.set("yem_attname", afterUpload.getString("fattachmentname"));
                            aNew.set("yem_attid", afterUpload.getString("fnumber"));
                            aNew.set("yem_attaddress", fileaddress);
                            aNew.set("yem_breakpointime", breakpointtime);
                            // 更新文件物理地址
                            String imageurl = assAtlas.getString("yem_imageurl");
                            imageurl = imageurl + fileaddress + ";";
                            assAtlas.set("yem_imageurl", imageurl);
                            successMap.add(picturename);
                        } else {
                            logger.info("上传文件失败!!");
                        }
                    }
                    for (DynamicObject dynamicObject : pictureentry) {
                        String picturename = dynamicObject.getString("yem_picturename");
                        if (successMap.contains(picturename)) {
                            dynamicObject.set("yem_suyntype", "B");
                            dynamicObject.set("yem_syncdate", new Date());
                        }
                    }
                    SaveServiceHelper.save(new DynamicObject[]{assAtlas});
                }
            }
            SaveServiceHelper.save(new DynamicObject[]{plmObj});
        }
    }

    /**
     * 查询匹配的 总成图册明细
     * PLM：变更后父项编码 - 总成图册明细.编码
     * PLM：变更后子项编码 - 替换关系：ABC 替换编码，E（删除）：不匹配，D（新增）替换前编码
     *
     * @return
     */
    private DynamicObject queryMatchAssemblyAtlasDetails(DynamicObject plmObj, DynamicObject d) {
        QFilter qFilter = new QFilter("status", "=", "C");
        String exchangetype = d.getString("yem_exchangetype");
        String parentno = d.getString("yem_parent_now");
        String childno = d.getString("yem_child_now");
        qFilter.and("number", "=", parentno);
        if ("ABC".contains(exchangetype)) {
            qFilter.and("yem_entryentity.yem_enablesubno", "=", childno);
        }
        if ("D".equals(exchangetype)) {
            qFilter.and("yem_entryentity.yem_partnumber", "=", childno);
        }
        if ("E".equals(exchangetype)) {
            return null;
        }
        return BusinessDataServiceHelper.loadSingle("yem_em_assatlasdet", qFilter.toArray());
    }

    private List<DynamicObject> getImageInfo(DynamicObjectCollection pictureentry, String imageName) {
        List<DynamicObject> list = new ArrayList<>();
        for (DynamicObject d : pictureentry) {
            String picturename = d.getString("yem_picturename");
            if (StringUtils.containsIgnoreCase(picturename, imageName)) {
                list.add(d);
            }
        }
        return list;
    }


    private Date getBreakPointTime(DynamicObjectCollection detail, String partno) {
        for (DynamicObject d : detail) {
            String exchangetype = d.getString("yem_exchangetype");
            String detailPartNo;
            if ("D".equals(exchangetype)) {
                detailPartNo = d.getString("yem_parent_now");
            } else {
                detailPartNo = d.getString("yem_textfield");
            }

            if (!"B".equals(d.get("yem_invokstatus"))) {
                continue;
            }

            if (partno.lastIndexOf("-") != -1) {
                partno = partno.substring(0, partno.lastIndexOf("-")).trim();
            }

            if (YEM.isNotEmpty(detailPartNo)) {
                detailPartNo = detailPartNo.trim();
            }

            if (YEM.isNotEmpty(detailPartNo) && YEM.isNotEmpty(partno)) {
                if (StringUtils.containsIgnoreCase(detailPartNo, partno)) {
                    return d.getDate("yem_invoktime");
                }
            }
        }
        return null;
    }
}
