package com.ai.da.common.utils;

import org.apache.logging.log4j.util.BiConsumer;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CopyUtil {

    public static <T> T copyObject(Object source, Class<T> tClass) throws BeansException {
        return entityToModel(source, tClass);
    }

    public static <F, T> List<T> copyList(List<F> source, Class<T> tClass) {
        if (source == null || source.isEmpty()) {
            return new ArrayList<>();
        }
        List<T> tList = new ArrayList<>();
        for (F f : source) {
            T t = entityToModel(f, tClass);
            tList.add(t);
        }
        return tList;
    }

    public static <F, T> List<T> copyList(List<F> source, Class<T> tClass, BiConsumer<F, T> consumer) {
        if (source == null || source.isEmpty()) {
            return new ArrayList<>();
        }
        List<T> tList = new ArrayList<>();
        for (F f : source) {
            T t = entityToModel(f, tClass);
            consumer.accept(f, t);
            tList.add(t);
        }
        return tList;
    }

    public static List<String> copyListToString(List source, String fieldName) {

        List<String> list = new ArrayList<>();
        if (null == source || source.isEmpty()) {
            return list;
        }

        for (int i = 0; i < source.size(); i++) {
            try {
                Class c = source.get(i).getClass();
                if (null != c) {
                    Method methodGetKey = c.getMethod(fieldName);
                    String key = "" + methodGetKey.invoke(source.get(i));
                    list.add(key);
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        return list;
    }

    /**
     * 复制对象
     *
     * @param entity
     * @param modelClass
     * @param <F>
     * @param <T>
     * @return
     */
    private static <F, T> T entityToModel(F entity, Class<T> modelClass) {
        Object model = null;
        if (entity == null || modelClass == null) {
            return null;
        }
        try {
            model = modelClass.newInstance();
        } catch (Exception e) {
            //忽略
        }
        BeanUtils.copyProperties(entity, model);
        return (T) model;
    }

    public static <K, V, F> Map<K, V> listToMap(List<F> list, Class<V> c) {
        List<V> vList = CopyUtil.copyList(list, c);
        return list2Map(vList, c);
    }

    public static <K, V, F> Map<K, V> listToMap(List<F> list, Class<V> c, String fieldName) {
        List<V> vList = CopyUtil.copyList(list, c);
        return list2Map(vList, c, fieldName);
    }

    public static <K, V> Map<K, V> list2Map(List<V> list, Class<V> c) {
        return list2Map(list, c, "getId");
    }


    public static <K, V> Map<K, V> list2Map(List<V> list, Class<V> c, String fieldName) {
        Map<K, V> map = new HashMap<>();
        if (list != null) {
            try {
                Method methodGetKey = c.getMethod(fieldName);
                for (int i = 0; i < list.size(); i++) {
                    V value = list.get(i);
                    @SuppressWarnings("unchecked")
                    K key = (K) methodGetKey.invoke(list.get(i));
                    map.put(key, value);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return map;
    }

}
