package com.cim.idm.wmsextend.generic.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Element;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @author 10862131
 * @date 2022年08月17日 14:23
 */
public class ElementUtil {

    private static Log logger = LogFactory.getLog(ElementUtil.class);

    /**
     * 构建map到element
     * Map<String,Object> map  = new HashMap<String,Object>();
     * map.put("lotName","1212122");
     * <p>
     * List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
     * Map<String,Object> map1 = new HashMap<>();
     * map1.put("productName","12121");
     * list.add(map1);
     * <p>
     * Map<String,Object> map2 = new HashMap<>();
     * map2.put("productName","12121");
     * list.add(map2);
     * <p>
     * map.put("productList",list);
     * <p>
     * Element element = buildMapMessage(map);
     *
     * <Body>
     * <lotName>1212122</lotName>
     * <productList>
     * <product>
     * <productName>12121</productName>
     * </product>
     * <product>
     * <productName>12121</productName>
     * </product>
     * </productList>
     * </Body>
     *
     * @param map
     */
    public static Element buildMapMessage(Map<String, Object> map) {
        Element element = new Element("Body");
        buildMessageMapToElement(element, map);
        return element;
    }
    /**
     * 构建map到element
     * Map<String,Object> map  = new HashMap<String,Object>();
     * map.put("lotName","1212122");
     * <p>
     * List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
     * Map<String,Object> map1 = new HashMap<>();
     * map1.put("productName","12121");
     * list.add(map1);
     * <p>
     * Map<String,Object> map2 = new HashMap<>();
     * map2.put("productName","12121");
     * list.add(map2);
     * <p>
     * map.put("productList",list);
     * <p>
     * Element element = buildMapMessage(map);
     *
     * <Body>
     * <lotName>1212122</lotName>
     * <productList>
     * <product>
     * <productName>12121</productName>
     * </product>
     * <product>
     * <productName>12121</productName>
     * </product>
     * </productList>
     * </Body>
     *
     * @param map
     */
    public static Element buildMapReturnMessage(Map<String, Object> map) {
        Element element = new Element("Return");
        buildMessageMapToElement(element, map);
        return element;
    }

    /**
     * 扩展json数组自解析为List<Map>
     * @param map
     * @return
     */
    public static Element buildMapMessageExtend(Map<String, Object> map) {
        Element element = new Element("Body");
        buildMessageMapToElementExtend(element, map);
        return element;
    }

    /**
     * 解析map到element
     *
     * @param element
     * @param map
     */
    private static void buildMessageMapToElement(Element element, Map<String, Object> map) {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey().toUpperCase();
            if (key.toUpperCase().contains("LIST")) {
                List<Map<String, Object>> list = (List<Map<String, Object>>) entry.getValue();
                Element listElement = new Element(key);
                for (Map<String, Object> childMap : list) {
                    Element childElement = new Element(key.substring(0, key.indexOf("LIST")));
                    buildMessageMapToElement(childElement, childMap);
                    listElement.addContent(childElement);
                }
                element.addContent(listElement);
            } else {
                Element childElement = new Element(key);
                if (entry.getValue() instanceof Map) {
                    buildMessageMapToElement(childElement, (Map<String, Object>) entry.getValue());
                } else {
                    if (entry.getValue() == null) {
                        childElement.setText("");
                    } else {
                        childElement.setText(entry.getValue() + "");
                    }

                }
                element.addContent(childElement);
            }
        }
    }

    private static void buildMessageMapToElementChildExtend(Element element, Map<String, Object> map) {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey().toUpperCase();
            if (key.toUpperCase().contains("LIST")) {
                List<Map<String, Object>> list = (List<Map<String, Object>>) entry.getValue();
                Element listElement = new Element(key);
                for (Map<String, Object> childMap : list) {
                    Element childElement = new Element(key.substring(0, key.indexOf("LIST")));
                    buildMessageMapToElementChildExtend(childElement, childMap);
                    listElement.addContent(childElement);
                }
                element.addContent(listElement);
            } else {
                Element childElement = new Element(key);
                if (entry.getValue() instanceof Map) {
                    buildMessageMapToElementChildExtend(childElement, (Map<String, Object>) entry.getValue());
                } else {
                    if (entry.getValue() == null) {
                        childElement.setText("");
                    } else {
                        String value = entry.getValue()+"";
                        if(key.equalsIgnoreCase("validDate")){
                            value = value.replace("T"," ");
                        }
                        else  if(key.equalsIgnoreCase("invalidDate")){
                            value = value.replace("T"," ");
                        }
                        childElement.setText(value + "");
                    }

                }
                element.addContent(childElement);
            }
        }
    }

    private static void buildMessageMapToElementExtend(Element element, Map<String, Object> map) {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey().toUpperCase();
            Object object = entry.getValue();
            if (object instanceof Collection) {
                List<Map<String, Object>> list = (List<Map<String, Object>>) entry.getValue();
                Element listElement = new Element(key+"LIST");
                for (Map<String, Object> childMap : list) {
                    Element childElement = new Element(key);
                    buildMessageMapToElementChildExtend(childElement, childMap);
                    listElement.addContent(childElement);
                }
                element.addContent(listElement);
            } else {
                Element childElement = new Element(key);
                if (entry.getValue() instanceof Map) {
                    buildMessageMapToElementChildExtend(childElement, (Map<String, Object>) entry.getValue());
                } else {
                    if (entry.getValue() == null) {
                        childElement.setText("");
                    } else {
                        childElement.setText(entry.getValue() + "");
                    }

                }
                element.addContent(childElement);
            }
        }
    }


    /**
     * 解析bean到map
     *
     * @param obj
     * @return Map
     */
    public static Map<String, Object> convertBeanToMap(Object obj) {
        Map<String, Object> map = new HashMap<String, Object>(16);
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                // 过滤class属性
                if (!"class".equals(key)) {
                    // 得到property对应的getter方法
                    Method getter = property.getReadMethod();
                    Object value = getter.invoke(obj);

                    map.put(key, value);
                }
            }
        } catch (Exception e) {
            logger.error("transBean2Map Error ", e);
        }
        return map;
    }

    /**
     * 处理beanlist 到 maplist
     *
     * @param objList
     * @param <T>
     * @return List
     */
    public static <T> List<Map<String, Object>> convertListBeanToListMap(List<T> objList) {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (T obj : objList) {
            Map<String, Object> map = convertBeanToMap(obj);
            list.add(map);
        }
        return list;
    }

    /**
     * @param obj
     * @return Map
     */
    private static Map<String, Object> convertMap(Object obj) {
        Class c = obj.getClass();
        Field[] f = c.getDeclaredFields();
        Map<String, Object> map = new HashMap<String, Object>(16);
        for (Field fie : f) {
            try {
                //取消语言访问检查
                fie.setAccessible(true);
                //获取私有变量值
                map.put(fie.getName(), fie.get(obj));
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        //获取父类的私有属性
        for (Field fie : c.getSuperclass().getDeclaredFields()) {
            try {
                //取消语言访问检查
                fie.setAccessible(true);
                //获取私有变量值
                map.put(fie.getName(), fie.get(obj));
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return map;
    }

    /**
     * @param element
     * @return Map
     */
    public static Map<String, Object> parseElementToMap(Element element) {
        Map<String, Object> result = new HashMap<>(16);
        List<Element> list = element.getChildren();
        for (Element e : list) {
            parseElementToMap(e, result);
        }
        return result;
    }

    /**
     * @param element
     * @param map
     */
    private static void parseElementToMap(Element element, Map<String, Object> map) {
        String listStr = "LIST";
        if (element.getName().contains(listStr)) {
            List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
            List<Element> list = element.getChildren();
            for (Element listElement : list) {
                Map<String, Object> beanMap = new HashMap<String, Object>(16);
                List<Element> beanList = listElement.getChildren();
                for (Element bean : beanList) {
                    parseElementToMap(bean, beanMap);
                }
                listMap.add(beanMap);
            }
            map.put(element.getName(), listMap);
        } else {
            if (element.getChildren().size() <= 0) {
                map.put(element.getName(), element.getText());
            } else {
                map.put(element.getName(), parseElementToMap(element));
            }
        }
    }


}
