package com.zm.order.tool.server.utils;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @Description 转换
 * @Author: cb
 * @Date: 2019/12/9 10:23
 */
public class MapperUtils {

    /**
     * 将map装换为javabean对象,删除map中和bean属性名相同的的key
     *
     * @param map 接受map集合
     */

    public static void move(Map<String, Object> map, Object root) {
        try {
            //如果map集合为空,结束方法
            if (CollectionUtils.isEmpty(map) || Objects.isNull(root)) {
                return;
            }
            Iterator it = map.entrySet().iterator();
            Class clazz = root.getClass();
            Field[] fields = clazz.getDeclaredFields();
            List<String> propertyNameList = Lists.newArrayList();
            for (int i = 0; i < fields.length; i++) {
                propertyNameList.add(fields[i].getName());
            }
            while (it.hasNext()) {
                Map.Entry<String, Object> entry = (Map.Entry) it.next();
                String fieldKey = entry.getKey();
                if (propertyNameList.contains(fieldKey)) {
                    Field field = clazz.getDeclaredField(fieldKey);
                    field.setAccessible(true);
                    if (field.getType().equals(Date.class)) {
                        Long milliSeconds = (Long) entry.getValue();
                        Calendar calendar = Calendar.getInstance();
                        calendar.setTimeInMillis(milliSeconds);
                        field.set(root, calendar.getTime());
                    } else {
                        field.set(root, entry.getValue());
                    }
                    it.remove();
                } else if (fieldKey.contains(".")) {
                    String firstField = fieldKey.substring(0, fieldKey.indexOf("."));
                    if (propertyNameList.contains(firstField)) {
                        trans(fieldKey, entry.getValue(), root, root.getClass());
                        it.remove();
                    }
                }
            }
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            throw new RuntimeException(throwable.getMessage());
        }
    }

    public static Object trans(String key, Object value, Object root, Class clazz) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
        int index = key.indexOf(".");
        String property;
        if (index < 0) {
            property = key;
            key = "";
        } else {
            property = key.substring(0, index);
            key = key.substring(index + 1);
        }
        if (isPrimitive(root)) {
            throw new IllegalAccessException("对象不能为基本数据类型");
        }
        if (clazz.equals(Map.class) || clazz.equals(HashMap.class)) {
            if (StringUtils.isEmpty(key)) {
                ((Map) root).put(property, value);
            } else {
                Object object = ((Map) root).get(property);
                if (object == null) {
                    object = new HashMap<>(16);
                }
                ((Map) root).put(property, trans(key, value, object, object.getClass()));
            }
        } else if (clazz.equals(String.class)) {
            Map<String, Object> map;
            if (StringUtils.isEmpty(root)) {
                map = Maps.newHashMap();
            } else {
                map = JSON.parseObject((String) root, Map.class);
            }
            if (StringUtils.isEmpty(key)) {
                map.put(property, value);
            } else {
                Object object = map.get(property);
                if (object == null) {
                    object = new HashMap<>(16);
                }
                map.put(property, trans(key, value, object, object.getClass()));
            }
            root = JSON.toJSONString(map);
        } else {
            Field field = clazz.getDeclaredField(property);
            field.setAccessible(true);
            if (StringUtils.isEmpty(key)) {
                field.set(root, value);
            } else {
                Object object = field.get(root);
                if (object == null) {
                    if (field.getType().equals(Map.class)) {
                        object = new HashMap<>(16);
                    } else {
                        object = field.getType().newInstance();
                    }
                }
                field.set(root, trans(key, value, object, field.getType()));
            }
        }
        return root;
    }

    /**
     * 判断一个对象是否是基本类型或基本类型的封装类型
     */
    public static boolean isPrimitive(Object obj) {
        try {
            return ((Class<?>) obj.getClass().getField("TYPE").get(null)).isPrimitive();
        } catch (Exception e) {
            return false;
        }
    }
}
