package com.huigou.topsun.util;

import org.springframework.stereotype.Component;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * PersistUtil 持久化工具
 *
 * @author qinzhenguan
 * @createDate 2023/12/30 10:49
 **/
@Component
public class PersistTool {

    @PersistenceContext(unitName = "system")
    private EntityManager entityManager;

    /**
     * description  持久化数据.                              <br>&nbsp;&nbsp;&nbsp;&nbsp;
     * Entity 时，如果 ID 为空执行 Persist，否则执行 Merge       <br>&nbsp;&nbsp;&nbsp;&nbsp;
     * List 时，要求数据集格式 :                                 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
     * HashMap {”add“: List< Entity >,”up“: List< Entity >,”del“: List< Entity >}
     * @param entitys  持久化数据集合 Set { Entity, HashMap }
     * @author qinzhenguan
     * @createDate 2023/12/26 16:44
     */
    public void persistEntitys(Set<Object> entitys) {
        entitys = entitys.stream().filter(Objects::nonNull).collect(Collectors.toSet());
        for(Object item : entitys) {
            if(item instanceof Map) {
                persistList(uncheckedCast(((Map<?, ?>) item).get("add")), "save");
                persistList(uncheckedCast(((Map<?, ?>) item).get("up")), "save");
                persistList(uncheckedCast(((Map<?, ?>) item).get("del")), "remove");
            } else {
                persistEntity(item);
            }
            entityManager.flush();
            entityManager.clear();
        }
    }

    /***
     * description  持久化 List
     * @param list  操作的 List
     * @param type  操作类似 save， remove
     * @author qinzhenguan
     * @createDate 2023/12/26 16:33
     */
    public void persistList(List<Class<?>> list, String type) {
        if(list == null || list.isEmpty()) {
            return;
        }
        for(int i= 0; i < list.size(); i++) {
            if("remove".equals(type)) {
                removeEntity(list.get(i));
            } else {
                persistEntity(list.get(i));
            }
            if(i % 80 == 0 || i == (list.size() - 1)) {
                entityManager.flush();
                entityManager.clear();
            }
        }
    }

    /***
     * description  持久化实体 (无 ID 时执行插入，有 ID 时执行更新)
     * @param entity   操作的 Entity
     * @author qinzhenguan
     * @createDate 2023/12/26 16:32
     */
    public void persistEntity(Object entity) {
        Class<?> clazz = entity.getClass();
        for(Field field : clazz.getDeclaredFields()) {
            if("id".equals(field.getName())) {
                try {
                    field.setAccessible(true);
                    BigDecimal id = (BigDecimal) field.get(entity);
                    if(id == null){
                        field.set(entity, String.valueOf(Snowflake.nextId()));
                        entityManager.persist(entity);
                    } else {
                        entityManager.merge(entity);
                    }
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    /***
     * description 移除实体
     * @param entity  操作的 Entity
     * @author qinzhenguan
     * @createDate 2023/12/26 16:31
     */
    public void removeEntity(Object entity) {
        if(entity == null) { return; }
        entityManager.remove(entity);
    }

    @SuppressWarnings("unchecked")
    public static <T> T uncheckedCast(Object obj) {
        if(obj != null) {
            return (T) obj;
        }
        return null;
    }

}