package com.yeejoin.amos.boot.module.hygf.api.util;

import org.springframework.beans.BeanUtils;

import java.lang.reflect.Field;

public class BeanDtoUtils {


    /**
     * Dot ,Vo ,Entity 相互转换
     *
     * @param source      原数据
     * @param targetClass 目标类
     * @param <T>         泛型类
     * @return 转换返回值
     */
    public static <T> T convert(Object source, Class<T> targetClass) {
        // 判断source是否为空
        if (source == null) {
            return null;
        }
        // 判断targetClass是否为空
        if (targetClass == null) {
            return null;
        }
        try {
            // 创建新的对象实例
            T target = targetClass.newInstance();
            // 把原对象数据拷贝到新对象
            BeanUtils.copyProperties(source, target);
            // 返回新对象
            return target;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    public static <S, T> void copyPropertiesNonNull(S source, T target) {
        if (source == null || target == null) {
            throw new IllegalArgumentException("Source and target cannot be null");
        }

        // 使用反射获取源对象的所有属性
        Field[] sourceFields = source.getClass().getDeclaredFields();

        for (Field sourceField : sourceFields) {
            if (sourceField.getName().equals("serialVersionUID")){
                continue;
            }
            sourceField.setAccessible(true);
            // 获取目标对象中对应的属性
            try {
                Field targetField = target.getClass().getDeclaredField(sourceField.getName());
                targetField.setAccessible(true);
                // 获取源对象的属性值
                Object sourceValue = sourceField.get(source);
                // 如果源对象的属性值不是 null，则复制到目标对象
                if (sourceValue != null ) {
                    targetField.set(target, sourceValue);
                }
            } catch (NoSuchFieldException e) {
                // 如果目标对象没有对应的属性，则忽略
            } catch (IllegalAccessException e) {
                // 如果访问属性时发生异常，则抛出运行时异常
                throw new RuntimeException(e);
            }
        }
    }



    public static <S, T> void copyPropertiesAllNonNull(S source, T target) {
        if (source == null || target == null) {
            throw new IllegalArgumentException("Source and target cannot be null");
        }

        Class<?> sourceClass = source.getClass();
        // 遍历源对象的所有类（包括父类）
        while (sourceClass != null && !sourceClass.equals(Object.class)) {
            Field[] sourceFields = sourceClass.getDeclaredFields();
            for (Field sourceField : sourceFields) {
                //静态常量字段忽略 因为是类级别不是实例
                if (sourceField.getName().equals("serialVersionUID")) {
                    continue;
                }
                sourceField.setAccessible(true);

                try {
                    // 尝试在目标对象的类层次结构中查找对应的字段
                    Field targetField = findField(target.getClass(), sourceField.getName());
                    if (targetField != null) {
                        targetField.setAccessible(true);
                        // 获取源对象的属性值
                        Object sourceValue = sourceField.get(source);
                        // 如果源对象的属性值不是 null，则复制到目标对象
                        if (sourceValue != null) {
                            targetField.set(target, sourceValue);
                        }
                    }
                } catch (IllegalAccessException e) {
                    // 如果访问属性时发生异常，则抛出运行时异常
                    throw new RuntimeException(e);
                }
            }
            // 继续处理父类
            sourceClass = sourceClass.getSuperclass();
        }
    }

    // 辅助方法，用于在目标对象的类层次结构中查找字段
    private static Field findField(Class<?> clazz, String name) {
        for (Class<?> c = clazz; c != null; c = c.getSuperclass()) {
            try {
                return c.getDeclaredField(name);
            } catch (NoSuchFieldException e) {
                // 忽略并继续查找
            }
        }
        return null; // 如果没有找到字段，则返回null
    }
}
