package com.energy.manage.service.util;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import lombok.SneakyThrows;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.cglib.beans.BeanMap;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 实体转换
 */
public class BeanMapUtils {

    /**
     * 将实体类对象属性转化为map对象
     * @param t
     * @param <T>
     * @return
     */
    public static <T> Map<String, Object> beanToMap(T t) {
        Map<String, Object> map = new HashMap<>();
        if (t != null) {
            if (t instanceof JSONObject){
                return (JSONObject)t;
            }
            BeanMap beanMap = BeanMap.create(t);
            for (Object key : beanMap.keySet()) {
                map.put(key.toString(), beanMap.get(key));
            }
        }
        return map;
    }


    /**
     * 将map对象中转化为实体类对象
     * @param map
     * @param clazz
     * @param <T>
     * @return
     * @throws Exception
     */
    public static <T> T mapToBean(Map<String, Object> map,Class<T> clazz){
        T bean = null;
        try {
            bean = clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        if (bean instanceof JSONObject){
            JSONObject jsonObject = (JSONObject)bean;
            Set<Map.Entry<String, Object>> entries = map.entrySet();
            for (Map.Entry<String, Object> entry : entries) {
                jsonObject.put(entry.getKey(),entry.getValue());
            }
            return (T)jsonObject;
        }
        BeanMap beanMap = BeanMap.create(bean);
        beanMap.putAll(map);
        return bean;
    }

    /**
     * 通过lambda表达式将List<JavaBean>转化为List<Map<String, Object>>
     * @param objList
     * @param <T>
     * @return
     */
    public static <T> List<Map<String, Object>> listBeanToListMap(List<T> objList) {
        return objList.stream().map(new Function<T, Map<String, Object>>() {
            @Override
            public Map<String, Object> apply(T t) {
                Map<String,Object> map = Maps.newHashMap();
                if (t instanceof JSONObject){
                    return (JSONObject)t;
                }
                BeanMap beanMap = BeanMap.create(t);
                for (Object key : beanMap.keySet()) {
                    map.put(key.toString(), beanMap.get(key));
                }
                return map;
            }
        }).collect(Collectors.toList());
    }

    /**
     * 通过lambda表达式将List<Map<String, Object>>转化为List<JavaBean>
     * @param mapList
     * @param <T>
     * @return
     */
    public static <T> List<T> listMapToListBean(List<Map<String,Object>> mapList,Class<T> clazz) {
        return mapList.stream().map(new Function<Map<String, Object>,T>() {
            @SneakyThrows
            @Override
            public T apply(Map<String, Object> map) {
                T t = clazz.newInstance();
                if (t instanceof JSONObject){
                    return (T)map;
                }
                BeanMap beanMap = BeanMap.create(t);
                beanMap.putAll(map);
                return t;
            }
        }).collect(Collectors.toList());
    }



    public static <T> List<T> convertListMapToJavaBean(List<Map<String, Object>> listMaps, Class<T> beanClass) {
        List<T> listBeans = new ArrayList<>();
        for (Map<String, Object> map : listMaps) {
            T bean;
            try {
                bean = beanClass.newInstance();
                for (Map.Entry<String, Object> entry : map.entrySet()) {
                    String fieldName = entry.getKey();
                    Object fieldValue = entry.getValue();
                    // 使用反射设置JavaBean的字段值
                    BeanUtils.setProperty(bean, fieldName, fieldValue);
                }
                listBeans.add(bean);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return listBeans;
    }


}
