package com.yem.wm.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.yem.wm.sys.utils.SpecialProcessingHelper;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.entity.OrmLocaleValue;
import kd.bos.dataentity.metadata.IDataEntityProperty;
import kd.bos.dataentity.metadata.IDataEntityType;
import kd.bos.dataentity.metadata.ISimpleProperty;
import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
import kd.bos.dataentity.metadata.dynamicobject.DynamicLocaleProperty;
import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
import kd.bos.dataentity.utils.StringUtils;
import kd.bos.entity.property.BasedataProp;
import kd.bos.entity.property.BooleanProp;
import kd.bos.entity.property.DateProp;
import kd.bos.entity.property.DateTimeProp;
import kd.bos.entity.property.DecimalProp;
import kd.bos.entity.property.EntryProp;
import kd.bos.entity.property.LongProp;
import kd.bos.entity.property.MulBasedataProp;
import kd.bos.orm.ORM;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;

/**
 * 业务实体工具类
 *
 * @author longh
 * @description:
 * @date 2021年11月9日 下午7:09:02
 */
public class DynamicObjectUtil {

    /**
     * 拷贝对象数据 分录清空全覆盖 主键清空
     *
     * @param from
     * @param to
     */
    public static void copyDynamicObject(DynamicObject from, DynamicObject to) {
        copyDynamicObject(from, to, 2, false, true, true);
    }

    /**
     * 拷贝对象数据 包含分录数据
     * 从 from 拷贝到 to
     * 以 to 有的属性 从 from 中获取
     *
     * @param from
     * @param to
     * @param entryCopyType        1 分录不处理 2 分录清空全覆盖 3 分录追加 4 分录按ID覆盖
     * @param ignoreNull           空值 不设
     * @param isMulReset           重置多选主键
     * @param clearPrimarykeyValue 清除主键
     */
    public static void copyDynamicObject(DynamicObject from, DynamicObject to, int entryCopyType, boolean ignoreNull, boolean isMulReset, boolean clearPrimarykeyValue) {
        DynamicObjectType toType = to.getDynamicObjectType();
        DataEntityPropertyCollection toProperties = toType.getProperties();
        DynamicObjectType fromType = from.getDynamicObjectType();
        DataEntityPropertyCollection fromProperties = fromType.getProperties();

        for (IDataEntityProperty toProperty : toProperties) {
            String name = toProperty.getName();
            if (!fromProperties.containsKey(name)) {
                continue;
            }
            //分录处理
            if (toProperty instanceof EntryProp) {
                if (entryCopyType == 1) {
                    continue;
                }
                //分录对象
                DynamicObjectCollection toDynamicObjectCollection = to.getDynamicObjectCollection(name);
                if (entryCopyType == 2) {
                    toDynamicObjectCollection.clear();
                }
                DynamicObjectCollection fromDynamicObjectCollection = from.getDynamicObjectCollection(name);
                for (DynamicObject fromObj : fromDynamicObjectCollection) {
                    String fromEntryPk = fromObj.getPkValue() == null ? "" : fromObj.getPkValue().toString();
                    DynamicObject dynamicObject = null;
                    boolean isadd = false;//是追加的行
                    if (entryCopyType == 4 && fromEntryPk.length() > 0) {
                        for (DynamicObject toObj : toDynamicObjectCollection) {
                            String toEntryPk = toObj.getPkValue() == null ? "" : toObj.getPkValue().toString();
                            if (toEntryPk.length() == 0) {
                                continue;
                            }
                            if (toEntryPk.equals(fromEntryPk)) {
                                dynamicObject = toObj;
                                break;
                            }
                        }
                    }
                    if (dynamicObject == null) {
                        dynamicObject = new DynamicObject(toDynamicObjectCollection.getDynamicObjectType());
                        isadd = true;
                    }

                    copyDynamicObject(fromObj, dynamicObject, entryCopyType, ignoreNull, isMulReset, clearPrimarykeyValue);
                    if ((entryCopyType == 2 || entryCopyType == 3) && isadd) {
                        SpecialProcessingHelper.PrimaryInformation(toType,fromObj, dynamicObject);
                        toDynamicObjectCollection.add(dynamicObject);
                    }
                }
            }//多选基础资料类处理
            else if (toProperty instanceof MulBasedataProp && isMulReset) {
                MulBasedataProp mulBasedataProp = ((MulBasedataProp) toProperty);

                IDataEntityType itemType = mulBasedataProp.getItemType();
                ISimpleProperty primaryKey = itemType.getPrimaryKey();
                DynamicObjectCollection toColls = (DynamicObjectCollection) to.get(name);
                toColls.clear();
                DynamicObjectType toDynamicObjectType = toColls.getDynamicObjectType();

                DynamicObjectCollection fromColls = (DynamicObjectCollection) from.get(name);
                for (DynamicObject coll : fromColls) {
                    DynamicObject mulBaseData = new DynamicObject(toDynamicObjectType);
                    copyDynamicObject(coll, mulBaseData, 1, ignoreNull, false, false);
                    primaryKey.resetValue(mulBaseData);
                    toColls.add(mulBaseData);
                }
            }//多语言表处理
            else if (toProperty instanceof DynamicLocaleProperty) {
                DynamicLocaleProperty localeProperty = ((DynamicLocaleProperty) toProperty);

                IDataEntityType itemType = localeProperty.getItemType();
                ISimpleProperty primaryKey = itemType.getPrimaryKey();
                DynamicObjectCollection toColls = (DynamicObjectCollection) to.get(name);
                toColls.clear();
                DynamicObjectType toDynamicObjectType = toColls.getDynamicObjectType();

                DynamicObjectCollection fromColls = (DynamicObjectCollection) from.get(name);
                for (DynamicObject coll : fromColls) {
                    DynamicObject mulBaseData = new DynamicObject(toDynamicObjectType);
                    copyDynamicObject(coll, mulBaseData, 1, ignoreNull, false, false);
                    primaryKey.resetValue(mulBaseData);
                    toColls.add(mulBaseData);
                }
            }//字段处理
            else {
                if (ignoreNull && from.get(name) == null) {
                    continue;
                }
                to.set(name, from.get(name));
                SpecialProcessingHelper.PrimaryData(to,name, from);
            }
        }
        if (clearPrimarykeyValue) {
            ISimpleProperty toPrimaryKey = toType.getPrimaryKey();
            toPrimaryKey.resetValue(to);
        }
    }

    public static String getSelectfieldsFast(String entityKey, String... entityKeys) {
        String srcSelect = getSelectfields(entityKey);
        for (String key : entityKeys) {
            srcSelect = getEntrySelectfields(srcSelect, entityKey, key);
        }
        return srcSelect;
    }

    public static String getSelectfields(String entityKey) {
        return getSelectfields(entityKey, false);
    }

    @SuppressWarnings("rawtypes")
    public static String getSelectfields(String entityKey, boolean isNeedAlias) {
        DynamicObject obj = ORM.create().newDynamicObject(entityKey);
        Map allProsMap = getDifferDynamicProperties(obj);
        List allProsList = (List) allProsMap.get("allProList");
        List bdList = (List) allProsMap.get("bdList");
        StringBuilder sb = new StringBuilder();
        Iterator arg6 = allProsList.iterator();

        while (arg6.hasNext()) {
            String key = (String) arg6.next();
            if (bdList.contains(key)) {
                if (sb.length() > 0) {
                    sb.append(",");
                }

                if (isNeedAlias) {
                    sb.append(key).append(".id").append(" ").append(key);
                } else {
                    sb.append(key).append(".id");
                }
            } else if (!StringUtils.equals("materialentry", key) && !StringUtils.equals("billhead_lk", key)
                    && !StringUtils.equals("multilanguagetext", key)) {
                if (sb.length() > 0) {
                    sb.append(",");
                }

                sb.append(key);
            }
        }

        return sb.toString();
    }

    public static String getEntrySelectfields(String srcSelect, String entityKey, String entryKey) {
        return getEntrySelectfields(srcSelect, entityKey, entryKey, false);
    }

    @SuppressWarnings("rawtypes")
    public static String getEntrySelectfields(String srcSelect, String entityKey, String entryKey, boolean isNeedAlias) {
        DynamicObject entry = ORM.create().newDynamicObject(entityKey + "." + entryKey);
        Map allProsMap = getDifferDynamicProperties(entry);
        List allProsList = (List) allProsMap.get("allProList");
//		List bdList = (List) allProsMap.get("bdList");
        StringBuilder sb = new StringBuilder();
        sb.append(srcSelect);
        Iterator arg8 = allProsList.iterator();

        while (arg8.hasNext()) {
            String key = (String) arg8.next();
            if (sb.length() > 0) {
                sb.append(",");
            }

            sb.append(entryKey).append(".").append(key);
            if (isNeedAlias) {
                sb.append(" ").append(key);
            }
        }

        return sb.toString();
    }

    public static String getEntrySelectfields(String srcSelect, String entityKey, String entryKey, String childentryKey) {
        return getEntrySelectfields(srcSelect, entityKey, entryKey, childentryKey, false);
    }

    @SuppressWarnings("rawtypes")
    public static String getEntrySelectfields(String srcSelect, String entityKey, String entryKey, String childentryKey, boolean isNeedAlias) {
        DynamicObject entry = ORM.create().newDynamicObject(entityKey + "." + entryKey + "." + childentryKey);
        String leftString = childentryKey;
        Map allProsMap = getDifferDynamicProperties(entry);
        List allProsList = (List) allProsMap.get("allProList");
//		List bdList = (List) allProsMap.get("bdList");
        StringBuilder sb = new StringBuilder();
        sb.append(srcSelect);
        Iterator arg10 = allProsList.iterator();

        while (arg10.hasNext()) {
            String key = (String) arg10.next();
            if (!"entryentity_lk".equals(key) && !"materialentry_lk".equals(key)) {
                if (sb.length() > 0) {
                    sb.append(",");
                }

                sb.append(leftString).append(".").append(key);
                if (isNeedAlias) {
                    sb.append(" ").append(key);
                }
            }
        }

        return sb.toString();
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    public static Map<String, List<String>> getDifferDynamicProperties(DynamicObject dynamicObject) {
        HashMap differProMap = new HashMap();
        ArrayList allProList = new ArrayList();
        ArrayList bdList = new ArrayList();
        ArrayList dateList = new ArrayList();
        ArrayList decimalList = new ArrayList();
        ArrayList booleanList = new ArrayList();
        if (dynamicObject != null) {
            DataEntityPropertyCollection proptiesCol = dynamicObject.getDataEntityType().getProperties();
            Iterator arg7 = proptiesCol.iterator();

            label40:
            while (true) {
                while (true) {
                    IDataEntityProperty iDataEntityProperty;
                    do {
                        if (!arg7.hasNext()) {
                            break label40;
                        }

                        iDataEntityProperty = (IDataEntityProperty) arg7.next();
                    }//这里加了一个判空，多选基础资料类字段无表名时getAlias()方法获取到的值为空
                    while (iDataEntityProperty.getAlias() == null || iDataEntityProperty.getAlias().equals(""));

                    if (!(iDataEntityProperty instanceof LongProp)) {
                        allProList.add(iDataEntityProperty.getName());
                    }

                    if (!(iDataEntityProperty instanceof DateProp) && !(iDataEntityProperty instanceof DateTimeProp)) {
                        if (iDataEntityProperty instanceof BasedataProp) {
                            bdList.add(iDataEntityProperty.getName());
                        } else if (iDataEntityProperty instanceof DecimalProp) {
                            decimalList.add(iDataEntityProperty.getName());
                        } else if (iDataEntityProperty instanceof BooleanProp) {
                            booleanList.add(iDataEntityProperty.getName());
                        }
                    } else {
                        dateList.add(iDataEntityProperty.getName());
                    }
                }
            }
        }

        differProMap.put("allProList", allProList);
        differProMap.put("bdList", bdList);
        differProMap.put("dateList", dateList);
        differProMap.put("decimalList", decimalList);
        differProMap.put("booleanList", booleanList);
        return differProMap;
    }


    /**
     * @param entityNumber 单据编码
     * @param qfilter      查询条件
     * @param filedNumber  返回值map中key 是哪个字段的值
     * @param entryNumbers 单据体标识集合
     * @return map key为传参字段的值  value为数据实体
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public static Map<Object, DynamicObject> getFiledDynamicObject(String entityNumber, List<QFilter> qfilter, String filedNumber, String... entryNumbers) {
        Map<Object, DynamicObject> map = new HashMap();
        String selectfields = DynamicObjectUtil.getSelectfields(entityNumber, false);
        for (String entryNumber : entryNumbers) {
            selectfields = DynamicObjectUtil.getEntrySelectfields(selectfields, entityNumber, entryNumber, false);
        }
        DynamicObject[] loads = null;
        if (qfilter != null) {
            loads = BusinessDataServiceHelper.load(entityNumber, selectfields, qfilter.toArray(new QFilter[qfilter.size()]));
        } else {
            loads = BusinessDataServiceHelper.load(entityNumber, selectfields, null);
        }

        for (DynamicObject load : loads) {
            Object object = load.get(filedNumber);
            if (object instanceof OrmLocaleValue) {
                OrmLocaleValue str = (OrmLocaleValue) object;
                map.put(str.getLocaleValue(), load);
            } else {
                map.put(object, load);
            }

        }
        return map;
    }

}
