package com.eshore.gringotts.web.domain.base.service;

import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil;
import com.eshore.gringotts.web.domain.base.entity.LogicDeleteEntity;
import com.eshore.gringotts.web.domain.base.repository.SimpleRepository;
import com.eshore.gringotts.web.domain.service.UserService;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.collections.api.list.ImmutableList;

/**
 * @author lanyuanxiaoyao
 * @date 2024-11-21
 */
@Slf4j
public abstract class LogicDeleteService<ENTITY extends LogicDeleteEntity> extends SimpleServiceSupport<ENTITY> {
    private final EntityManager manager;

    public LogicDeleteService(SimpleRepository<ENTITY, Long> repository, UserService userService, EntityManager manager) {
        super(repository, userService);
        this.manager = manager;
    }

    @Override
    protected ImmutableList<Predicate> listPredicate(Root<ENTITY> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
        return super.listPredicate(root, query, builder).newWith(builder.equal(root.get("deleted"), false));
    }

    @Transactional(rollbackOn = Throwable.class)
    @Override
    public void remove(Long id) {
        String entityName = ClassUtil.getTypeArgument(this.getClass()).getSimpleName();
        Query query = manager.createQuery(StrUtil.format("update {} entity set deleted=true where id=?1", entityName));
        query.setParameter(1, id);
        query.executeUpdate();
    }
}
