package org.springblade.utils.excel.controller;


import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springblade.utils.excel.model.HomeDeviceImportModule;
import org.springframework.data.annotation.Id;

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.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author caizw
 * @createDate 2018/2/8
 * @description 反射工具类
 */
public class ReflectUtils {

	/**
	 * 获取实体类主键
	 *
	 * @param clazz
	 * @return
	 */
	public static Field getIdField(Class<?> clazz) {
		Field[] fields = clazz.getDeclaredFields();
		Field item = null;
		for (Field field : fields) {
			Id id = field.getAnnotation(Id.class);
			if (id != null) {
				field.setAccessible(true);
				item = field;
				break;
			}
		}
		if (item == null) {
			Class<?> superclass = clazz.getSuperclass();
			if (superclass != null) {
				item = getIdField(superclass);
			}
		}
		return item;
	}

	/**
	 * 根据主键名称获取实体类主键属性值
	 *
	 * @param clazz
	 * @param pkName
	 * @return
	 */
	public static Object getPkValueByName(Object clazz, String pkName) {
		try {
			String firstLetter = pkName.substring(0, 1).toUpperCase();
			String getter = "get" + firstLetter + pkName.substring(1);
			Method method = clazz.getClass().getMethod(getter, new Class[]{});
			Object value = method.invoke(clazz, new Object[]{});
			return value;
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 通过反射将 class1不为空的值赋值给class2
	 *
	 * @param class1
	 * @param class2
	 * @throws Exception
	 */
	public static void reflectClass1ToClass2(Object class1, Object class2) throws Exception {
		Field[] field = class1.getClass().getDeclaredFields();
		for (int i = 0; i < field.length; i++) {
			String name = field[i].getName();
			if ("serialVersionUID".equals(name)) {
				continue;
			}
			name = name.substring(0, 1).toUpperCase() + name.substring(1);
			Method m1 = class1.getClass().getMethod("get" + name);
			Object value = m1.invoke(class1);
			if (value != null) {
				Field f = field[i];
				f.setAccessible(true);
				f.set(class2, value);
			}
		}
	}

	/**
	 * 获取实体类 @Column 的其中一个属性名称
	 *
	 * @param clazz
	 * @return
	 */
	public static List<String> getColumnName(Class<?> clazz) {
		List<String> columnNameList = new ArrayList<>();

		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			Map<String, String> map = new ConcurrentHashMap<>();
			if (field.isAnnotationPresent(ExcelProperty.class)) {
				/**
				 * 获取字段名
				 */
				ExcelProperty declaredAnnotation = field.getDeclaredAnnotation(ExcelProperty.class);
				String column = declaredAnnotation.value()[0];
				map.put("ExcelProperty", column);
				columnNameList.add(column);
			}
		}
		return columnNameList;
	}

//	/**
//	 * 通过获取类上的@Table注解获取表名称
//	 *
//	 * @param clazz
//	 * @return
//	 */
//	public static Map<String, String> getTableName(Class<?> clazz) {
//		Map<String, String> map = new ConcurrentHashMap<>();
//		Table annotation = clazz.getAnnotation(Table.class);
//		String name = annotation.name();
//		String className = clazz.getSimpleName();
//		map.put("tableName", name);
//		map.put("className", className);
//		return map;
//	}

	public static Map<String, Object> transBean2Map(Object obj) {
		if (obj == null) {
			return null;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();
				if (!key.equals("class")) {
					Method getter = property.getReadMethod();
					Object value = getter.invoke(obj);
					map.put(key, value);
				}
			}
		} catch (Exception e) {
			System.out.println("transBean2Map Error " + e);
		}
		return map;
	}

	//json字符串转换为MAP
	public static Map jsonStrToMap(String s) {
		Map map = new HashMap();
		//注意这里JSONObject引入的是net.sf.json
		net.sf.json.JSONObject json = net.sf.json.JSONObject.fromObject(s);
		Iterator keys = json.keys();
		while (keys.hasNext()) {
			String key = (String) keys.next();
			String value = json.get(key).toString();
			if (value.startsWith("{") && value.endsWith("}")) {
				map.put(key, jsonStrToMap(value));
			} else {
				map.put(key, value);
			}

		}
		return map;
	}


	public static void main(String[] args) {
		Field idField = ReflectUtils.getIdField(HomeDeviceImportModule.class);
		List<String> colummaNames = ReflectUtils.getColumnName(HomeDeviceImportModule.class);
		colummaNames.forEach(item -> {
			System.out.println(item);
		});
	}
}
