package com.yem.wm.bc.change.business;

import com.yem.wm.bc.change.common.consts.ChangeTypeEnum;
import com.yem.wm.bc.common.CommonUtils;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.entity.OrmLocaleValue;
import kd.bos.dataentity.metadata.IDataEntityType;
import kd.bos.dataentity.metadata.dynamicobject.DynamicProperty;
import kd.bos.dataentity.resource.ResManager;
import kd.bos.entity.BasedataEntityType;
import kd.bos.entity.EntityType;
import kd.bos.entity.ValueMapItem;
import kd.bos.entity.property.*;
import kd.bos.servicehelper.inte.InteServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import kd.bos.util.StringUtils;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author 夜子
 * @ClassName XBillLogHelper
 * @description: 变更单单据日志帮助类
 * @date 2023年08月03日
 * @version: 1.0
 */
public class XBillLogHelper {
    public XBillLogHelper() {
    }

    public static Map<String, String> compareSrcBillNXBill(DynamicObject srcBill, DynamicObject xBill, Map<String, Map<String, String>> xBillEntryAndField) {
        if (srcBill != null && xBill != null) {
            HashMap<String, String> rs = new HashMap();
            String[] billfields = ChangeModelHelper.getCanLogProperty(xBill.getDynamicObjectType());
            StringBuilder billMD = new StringBuilder();
            billMD.append("### ").append(srcBill.getDataEntityType().getDisplayName()).append('【').append(srcBill.getString("billno")).append('】').append(ResManager.loadKDString("变更情况", "XBillLogHelper_0", "yem-yc-changemodel", new Object[0])).append(" ### \n --- \n").append("> ").append(ResManager.loadKDString("变更人：", "XBillLogHelper_1", "yem-yc-changemodel", new Object[0])).append(displayFieldValue(xBill.get("modifier"))).append("  \n").append("> ").append(ResManager.loadKDString("变更单日期：", "XBillLogHelper_2", "yem-yc-changemodel", new Object[0])).append(displayFieldValue(xBill.get("changebizdate"))).append("  \n").append("> ").append(ResManager.loadKDString("变更版本：", "XBillLogHelper_3", "yem-yc-changemodel", new Object[0])).append(xBill.get("version")).append("  \n").append("> ").append(ResManager.loadKDString("变更原因：", "XBillLogHelper_4", "yem-yc-changemodel", new Object[0])).append(xBill.get("changereason")).append("   \n").append("#### ").append(ResManager.loadKDString("变更内容", "XBillLogHelper_5", "yem-yc-changemodel", new Object[0])).append(" ####\n").append('|').append(ResManager.loadKDString("字段名称", "XBillLogHelper_6", "yem-yc-changemodel", new Object[0])).append('|').append(ResManager.loadKDString("原值", "XBillLogHelper_7", "yem-yc-changemodel", new Object[0])).append('|').append(ResManager.loadKDString("变更值", "XBillLogHelper_8", "yem-yc-changemodel", new Object[0])).append("|\n|-|-|-|\n");
            if (!CommonUtils.isNull(billfields)) {
                for(int fi = 0; fi < billfields.length; ++fi) {
                    try {
                        Object srcField = srcBill.get(billfields[fi]);
                        Object newField = xBill.get(billfields[fi]);
                        String s1 = MetaDataHelper.getPropertyAlias(srcBill.getDataEntityType(), billfields[fi]);
                        DynamicProperty srcdp = srcBill.getDynamicObjectType().getProperty(billfields[fi]);
                        String s2 = displayFieldValue(srcField, srcdp);
                        String s3 = displayFieldValue(newField, srcdp);
                        billMD.append('|').append(s1).append(' ').append('|').append(s2).append(' ').append('|').append(s3).append("|\n");
                    } catch (Exception ignored) {
                    }
                }
            }

            rs.put(xBill.getDataEntityType().getName(), billMD.toString());
            rs.put("mdText", billMD.toString());
            List<EntityType> entryEntities = ChangeModelHelper.getChildEntities(xBill.getDataEntityType());
            Iterator<EntityType> var16 = entryEntities.iterator();
            while(true) {
                EntityType entryEntity;
                do {
                    if (!var16.hasNext()) {
                        return rs;
                    }
                    entryEntity = (EntityType)var16.next();
                } while(xBillEntryAndField.get(entryEntity.getName()) == null);

                try {
                    srcBill.getDynamicObjectCollection(entryEntity.getName());
                } catch (Exception var14) {
                    continue;
                }

                String[] canLogProperty = ChangeModelHelper.getCanLogProperty(xBill.getDataEntityType(), entryEntity.getName());
                if (!CommonUtils.isNull(canLogProperty)) {
                    String billEntryMD = "\n" + String.format(ResManager.loadKDString("#### %s变更内容 ####", "XBillLogHelper_5", "yem-yc-changemodel", new Object[0]), entryEntity.getDisplayName()) + "\n";
                    billEntryMD = billEntryMD + genMDFormatString(srcBill, xBill, entryEntity.getName(), entryEntity.getName(), canLogProperty, (String)((Map)xBillEntryAndField.get(entryEntity.getName())).get("srcid"), (String)((Map)xBillEntryAndField.get(entryEntity.getName())).get("changetype"));
                    rs.put(entryEntity.getName(), billEntryMD);
                    rs.put("mdText", (String)rs.get("mdText") + billEntryMD);
                }
            }
        } else {
            return null;
        }
    }

    public static String genMDFormatString(DynamicObject srcBill, DynamicObject xBill, String entryName, String xEntryName, String[] billEntryFields, String SrcBillEntryID, String EntryChangeType) {
        StringBuilder billEntryMD = new StringBuilder("\n|");
        IDataEntityType srcBilldt = srcBill.getDataEntityType();

        for(int fi = 0; fi < billEntryFields.length; ++fi) {
            billEntryMD.append(MetaDataHelper.getEntryPropertyAlias(srcBilldt, entryName, billEntryFields[fi]));
            billEntryMD.append('|');
        }

        DynamicObjectCollection srcBillEntrys = srcBill.getDynamicObjectCollection(entryName);
        DynamicObjectCollection xBillEntrys = xBill.getDynamicObjectCollection(xEntryName);
        billEntryMD.append("\n|");

        int i;
        for(i = 0; i < billEntryFields.length; ++i) {
            billEntryMD.append(":-:|");
        }

        if (!CommonUtils.isNull(xBillEntrys)) {
            DynamicObject xBillEntry;
            for(i = 0; i < xBillEntrys.size(); ++i) {
                xBillEntry = (DynamicObject)xBillEntrys.get(i);
                long srcBillEntryID = xBillEntry.getLong(SrcBillEntryID);
                if (ChangeTypeEnum.UPDATE.getValue().equals(xBillEntry.get(EntryChangeType))) {
                    for (DynamicObject billEntry : srcBillEntrys) {
                        DynamicObject srcBillEntry = (DynamicObject) billEntry;
                        long xBillEntryID = (Long) srcBillEntry.getPkValue();
                        if (srcBillEntryID == xBillEntryID) {
                            StringBuilder rowMD = new StringBuilder("\n|");
                            boolean isChange = false;

                            for (String billEntryField : billEntryFields) {
                                Object srcField = srcBillEntry.get(billEntryField);
                                DynamicProperty srcdp = srcBillEntry.getDynamicObjectType().getProperty(billEntryField);
                                Object newField = xBillEntry.get(billEntryField);
                                DynamicProperty newdp = xBillEntry.getDynamicObjectType().getProperty(billEntryField);
                                if (compareField(srcField, newField)) {
                                    rowMD.append(displayFieldValue(newField, newdp));
                                    rowMD.append('|');
                                } else {
                                    rowMD.append(displayCompareFieldValue(srcField, srcdp, newField, newdp));
                                    rowMD.append('|');
                                    isChange = true;
                                }
                            }

                            if (isChange) {
                                billEntryMD.append(rowMD);
                            }
                        }
                    }
                }
            }

            int c;
            Object newField;
            DynamicProperty newdp;
            for(i = 0; i < xBillEntrys.size(); ++i) {
                xBillEntry = (DynamicObject)xBillEntrys.get(i);
                if (ChangeTypeEnum.ADDNEW.getValue().equals(xBillEntry.get(EntryChangeType))) {
                    billEntryMD.append("\n|");

                    for(c = 0; c < billEntryFields.length; ++c) {
                        newField = xBillEntry.get(billEntryFields[c]);
                        newdp = xBillEntry.getDynamicObjectType().getProperty(billEntryFields[c]);
                        String displayFieldValue = displayFieldValue(newField, newdp);
                        if (displayFieldValue.trim().isEmpty()) {
                            billEntryMD.append('|');
                        } else {
                            billEntryMD.append('*');
                            billEntryMD.append(displayFieldValue);
                            billEntryMD.append("*|");
                        }
                    }
                }
            }

            for(i = 0; i < xBillEntrys.size(); ++i) {
                xBillEntry = (DynamicObject)xBillEntrys.get(i);
                if (ChangeTypeEnum.CANCEL.getValue().equals(xBillEntry.get(EntryChangeType))) {
                    billEntryMD.append("\n|");

                    for(c = 0; c < billEntryFields.length; ++c) {
                        newField = xBillEntry.get(billEntryFields[c]);
                        newdp = xBillEntry.getDynamicObjectType().getProperty(billEntryFields[c]);
                        billEntryMD.append("~~");
                        billEntryMD.append(displayFieldValue(newField, newdp));
                        billEntryMD.append("~~|");
                    }
                }
            }
        }

        return billEntryMD.toString();
    }

    public static boolean compareField(Object srcField, Object newField) {
        if (srcField == null && newField == null) {
            return true;
        } else if (srcField instanceof OrmLocaleValue && ((OrmLocaleValue)srcField).isEmpty() && newField instanceof OrmLocaleValue && ((OrmLocaleValue)newField).isEmpty()) {
            return true;
        } else if (srcField instanceof BigDecimal && newField instanceof BigDecimal && srcField.equals(newField)) {
            return true;
        } else if (srcField instanceof DynamicObject && newField instanceof DynamicObject && ((DynamicObject)srcField).getPkValue().equals(((DynamicObject)newField).getPkValue())) {
            return true;
        } else if (newField != null && newField.equals(srcField)) {
            return true;
        } else if (srcField != null && srcField.equals(newField)) {
            return true;
        } else {
            if (srcField != null && newField != null) {
                String srcFieldStr = srcField.toString();
                String newFieldStr = newField.toString();
                if (srcFieldStr == null && newFieldStr == null) {
                    return true;
                }

                if (srcFieldStr != null && srcFieldStr.equals(newFieldStr)) {
                    return true;
                }
            }

            return false;
        }
    }

    public static String displayCompareFieldValue(Object srcField, DynamicProperty srcdp, Object newField, DynamicProperty newdp) {
        if (srcField == null && newField == null) {
            return "";
        } else if (srcField instanceof OrmLocaleValue && ((OrmLocaleValue)srcField).isEmpty() && newField instanceof OrmLocaleValue && ((OrmLocaleValue)newField).isEmpty()) {
            return "";
        } else if (newField != null && newField.equals(srcField)) {
            return "";
        } else if (srcField != null && srcField.equals(newField)) {
            return "";
        } else {
            if (srcField instanceof BigDecimal && newField instanceof BigDecimal) {
                if (((BigDecimal)srcField).compareTo((BigDecimal)newField) == 0) {
                    return "";
                }

                if (((BigDecimal)srcField).compareTo((BigDecimal)newField) < 0) {
                    return displayFieldValue(srcField, srcdp) + " >> **" + displayFieldValue(newField, newdp) + "**&uarr;";
                }

                if (((BigDecimal)srcField).compareTo((BigDecimal)newField) > 0) {
                    return displayFieldValue(srcField, srcdp) + " >> **" + displayFieldValue(newField, newdp) + "**&darr;";
                }
            }

            return displayFieldValue(srcField, srcdp) + " >> **" + displayFieldValue(newField, newdp) + "**";
        }
    }

    public static String displayFieldValue(Object newField) {
        if (newField == null) {
            return "";
        } else if (newField instanceof BigDecimal) {
            BigDecimal b = (BigDecimal)newField;
            return b.stripTrailingZeros().toPlainString();
        } else if (newField instanceof Date) {
            Date d = (Date)newField;
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            return df.format(d);
        } else if (newField instanceof Boolean) {
            Boolean b = (Boolean)newField;
            return b ? "Yes" : "No";
        } else if (newField instanceof DynamicObject) {
            DynamicObject dyo = (DynamicObject)newField;
            if (dyo.getDataEntityType() instanceof BasedataEntityType) {
                if (!"bd_materialsalinfo".equals(dyo.getDataEntityType().getName()) && !"bd_materialpurchaseinfo".equals(dyo.getDataEntityType().getName())) {
                    if ("bd_operator".equals(dyo.getDataEntityType().getName())) {
                        return dyo.getDynamicObject("operatorid").getString("name");
                    } else {
                        return "bd_supplierlinkman".equals(dyo.getDataEntityType().getName()) ? dyo.getString("contactperson") : dyo.getString("name");
                    }
                } else {
                    return dyo.getDynamicObject("masterid").getString("name");
                }
            } else {
                return dyo.toString();
            }
        } else {
            return newField.toString();
        }
    }

    public static String displayFieldValue(Object newField, DynamicProperty newdp) {
        if (newField == null) {
            return "";
        } else if (newField instanceof BigDecimal) {
            BigDecimal b = (BigDecimal)newField;
            return b.stripTrailingZeros().toPlainString();
        } else if (newField instanceof Date) {
            Date d = (Date)newField;
            String format = InteServiceHelper.getUserFormat(UserServiceHelper.getCurrentUserId()).getDateFormat().getDateFormat();
            SimpleDateFormat df = new SimpleDateFormat(format);
            return df.format(d);
        } else if (newField instanceof Boolean) {
            Boolean b = (Boolean)newField;
            return b ? ResManager.loadKDString("是", "XBillLogHelper_9", "yem-yc-changemodel", new Object[0]) : ResManager.loadKDString("否", "XBillLogHelper_10", "yem-yc-changemodel", new Object[0]);
        } else {
            if (newField instanceof DynamicObject) {
                DynamicObject dyo = (DynamicObject)newField;
                if (newdp instanceof BasedataProp) {
                    if (newdp instanceof FlexProp) {
                        return getTransString(dyo.toString());
                    }

                    BasedataProp bdProp = (BasedataProp)newdp;
                    return getTransString(bdProp.getDisplayValue(newField));
                }
            } else {
                if (newField instanceof DynamicObjectCollection) {
                    DynamicObjectCollection dyoCol = (DynamicObjectCollection)newField;
                    if (dyoCol.isEmpty()) {
                        return "";
                    }

                    if (newdp instanceof MulBasedataProp) {
                        if (newdp instanceof AttachmentProp) {
                            AttachmentProp panel = (AttachmentProp)newdp;
                            return getTransString(panel.getDisplayValue(newField));
                        }

                        MulBasedataProp mulbdPro = (MulBasedataProp)newdp;
                        return getTransString(mulbdPro.getDisplayValue(newField));
                    }

                    return getTransString(newField.toString());
                }

                if (newdp instanceof MulComboProp) {
                    MulComboProp cbPros = (MulComboProp)newdp;
                    return getTransString(cbPros.getItemByName((String)newField));
                }

                if (newdp instanceof ComboProp) {
                    ComboProp cbPro = (ComboProp)newdp;
                    List<ValueMapItem> cbItems = cbPro.getComboItems();

                    for(int i = 0; i < cbItems.size(); ++i) {
                        if (cbItems.get(i) != null) {
                            ValueMapItem cbitem = (ValueMapItem)cbItems.get(i);
                            if (newField.equals(cbitem.getValue())) {
                                return getTransString(cbitem.getName().toString());
                            }
                        }
                    }
                } else if (newField instanceof OrmLocaleValue) {
                    String str = ((OrmLocaleValue)newField).getLocaleValue();
                    if (str == null) {
                        return "";
                    }
                }
            }

            return getTransString(newField.toString());
        }
    }

    public static String getTransString(String str) {
        if (StringUtils.isNotEmpty(str)) {
            if (str.contains("|")) {
                str = str.replaceAll("\\|", "&#124;");
            }
        } else {
            str = "";
        }

        return str;
    }
}
