package com.sckw.core.utils;

import cn.hutool.core.bean.BeanUtil;
import com.sckw.core.model.constant.Global;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zk
 * @version V1.0
 * @Title: SupplyMapper
 * @Package com.wph.modules.supply.mapper
 * @Description: ()
 * @date 2019/5/15 001510:37
 */
public class BeanUtils extends BeanUtil {

    /**
     * 下划线拼接
     */
    public static final char UNDERLINE = '_';

    public static boolean checkFieldValueNull(Object bean) {
        boolean result = true;
        if (bean == null) {
            return true;
        }
        Class<?> cls = bean.getClass();
        Method[] methods = cls.getDeclaredMethods();
        Field[] fields = cls.getDeclaredFields();
        for (Field field : fields) {
            try {
                String fieldGetName = parGetName(field.getName());
                if (!checkGetMet(methods, fieldGetName)) {
                    continue;
                }
                Method fieldGetMet = cls.getMethod(fieldGetName, new Class[]{});
                Object fieldVal = fieldGetMet.invoke(bean, new Object[]{});
                if (fieldVal != null) {
                    if ("".equals(fieldVal)) {
                        result = true;
                    } else {
                        result = false;
                    }
                }
            } catch (Exception e) {
                continue;
            }
        }
        return result;
    }


    /**
     * 拼接某属性的 get方法
     *
     * @param fieldName
     * @return String
     */
    public static String parGetName(String fieldName) {
        if (null == fieldName || "".equals(fieldName)) {
            return null;
        }
        int startIndex = 0;
        if (fieldName.charAt(0) == UNDERLINE) {
            startIndex = 1;
        }
        return "get"
                + fieldName.substring(startIndex, startIndex + 1).toUpperCase()
                + fieldName.substring(startIndex + 1);
    }

    /**
     * 判断是否存在某属性的 get方法
     *
     * @param methods
     * @param fieldGetMet
     * @return boolean
     */
    public static boolean checkGetMet(Method[] methods, String fieldGetMet) {
        for (Method met : methods) {
            if (fieldGetMet.equals(met.getName())) {
                return true;
            }
        }
        return false;
    }

    /**
     *
     * @Title: isProperty
     * @Description: 判断对象是否存在某属性
     * @param bean 对象
     * @param propertyName 属性
     * @return
     * @return: boolean 有则反之true 反之false
     *
    public static boolean isProperty(Object bean, String propertyName){
    if (bean == null) {
    return false;
    }
    Class<?> cls = bean.getClass();
    PropertyDescriptor[] propertys = org.springframework.beans.BeanUtils.getPropertyDescriptors(cls);
    for (PropertyDescriptor property : propertys){
    String fieldName = property.getName();
    if(fieldName != null && propertyName != null && fieldName.equals(propertyName)){
    return true;
    }
    }
    return false;
    }*/


    /**
     * @param object
     * @return boolean
     * @description 判断当前对象是否为空
     * @author jiangwei
     * @date 2020/9/18 14:40
     **/
    public static boolean objCheckIsNull(Object object) {
        return objCheckIsNull(object, null, null);
    }

    /**
     * @param object           入参对象
     * @param excludeNameList  要剔除的属性名称,没有就传空集合或者null
     * @param excludeValueList 要剔除的数值,没有就传空集合或者null
     * @return boolean
     * @description 判断当前对象是否为空（包括所有属性为空）
     * 可选则在判断规则中剔除某一字段，或者某一值
     * @author jiangwei
     * @date 2020/5/22 10:14
     **/
    public static boolean objCheckIsNull(Object object, List<String> excludeNameList, List<Object> excludeValueList) {

        if (object == null) {
            return true;
        }
        // 得到类对象
        Class clazz = object.getClass();
        // 得到所有属性
        Field[] fields = clazz.getDeclaredFields();
        //判断入参
        boolean excludeNameListFlag = false;
        if (excludeNameList != null && excludeNameList.size() > 0) {
            excludeNameListFlag = true;
        }
        boolean excludeValueListFlag = false;
        if (excludeValueList != null && excludeValueList.size() > 0) {
            excludeValueListFlag = true;
        }
        //定义返回结果，默认为true
        boolean flag = true;
        for (Field field : fields) {
            field.setAccessible(true);
            Object fieldValue = null;
            String fieldName = null;
            try {
                //得到属性值
                fieldValue = field.get(object);
                //得到属性类型
                Type fieldType = field.getGenericType();
                //得到属性名
                fieldName = field.getName();
                //剔除指定属性名的属性值
                if (excludeNameListFlag) {
                    for (String s : excludeNameList) {
                        if (fieldName.equals(s)) {
                            fieldValue = null;
                        }
                    }
                }
                //剔除指定属性值
                if (excludeValueListFlag) {
                    for (Object obj : excludeValueList) {
                        if (fieldValue == obj) {
                            fieldValue = null;
                        }
                    }
                }
            } catch (IllegalArgumentException | IllegalAccessException e) {
                e.printStackTrace();
            }
            //只要有一个属性值不为null 就返回false 表示对象不为null 忽略序列化
            if (fieldValue != null && !"serialVersionUID".equals(fieldName)) {
                flag = false;
                break;
            }
        }
        return flag;
    }

    /**
     * @param bean         对象
     * @param propertyName 属性
     * @return
     * @Title: isProperty
     * @Description: 判断对象是否存在某属性
     * @return: boolean 有则反之true 反之false
     */
    public static boolean isProperty(Object bean, String propertyName) {
        if (bean == null) {
            return false;
        }
        Class<?> cls = bean.getClass();
        PropertyDescriptor[] propertys = org.springframework.beans.BeanUtils.getPropertyDescriptors(cls);
        for (PropertyDescriptor property : propertys) {
            String fieldName = property.getName();
            if (fieldName != null && propertyName != null && fieldName.equals(propertyName)) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param source 源对象
     * @param target 目标对象
     * @desc source 属性值赋值给target
     * @author zk
     * @date 2023/7/18
     **/
    public static void copyPropertiesValue(Object source, Object target) {
        // 获取实体类的所有属性，返回Field数组
        Field[] field = target.getClass().getDeclaredFields();
        // 遍历所有属性
        for (int j = 0; j < field.length; j++) {
            // 获取属性的名字
            String fieldName = field[j].getName();
            // 通过属性名称获取对象属性值
            Object value = BeanUtils.getProperty(source, fieldName);
            if (value != null) {
                // 为对象属性赋值
                BeanUtils.setProperty(target, fieldName, value);
            }
        }
    }

    public static Map<String, Object> convertToMap(Object yourObject) {
        Map<String, Object> map = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        try {
            Field[] fields = yourObject.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                String fieldName = field.getName();
                Object fieldValue = field.get(yourObject);
                map.put(fieldName, fieldValue);
            }
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        return map;
    }

}
