package dev.lions.unionflow.server.repository;

import dev.lions.unionflow.server.entity.BaseEntity;
import io.quarkus.hibernate.orm.panache.PanacheRepositoryBase;
import jakarta.persistence.EntityManager;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

/**
 * Repository de base pour les entités utilisant UUID comme identifiant
 * 
 * <p>
 * Étend PanacheRepositoryBase pour utiliser les fonctionnalités officielles de
 * Quarkus Panache avec UUID.
 * 
 * @param <T> Le type d'entité qui étend BaseEntity
 * @author UnionFlow Team
 * @version 5.0
 */
public abstract class BaseRepository<T extends BaseEntity> implements PanacheRepositoryBase<T, UUID> {

    @Inject
    protected EntityManager entityManager;

    protected final Class<T> entityClass;

    protected BaseRepository(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    /**
     * Trouve une entité par son UUID.
     */
    @Override
    public T findById(UUID id) {
        return entityManager.find(entityClass, id);
    }

    /**
     * Trouve une entité par son UUID (retourne Optional).
     */
    @Override
    public Optional<T> findByIdOptional(UUID id) {
        return Optional.ofNullable(findById(id));
    }

    /**
     * Persiste ou met à jour une entité.
     * Utilise merge si l'entité possède déjà un ID.
     */
    @Override
    @Transactional
    public void persist(T entity) {
        if (entity.getId() == null) {
            entityManager.persist(entity);
        } else {
            entityManager.merge(entity);
        }
    }

    /**
     * Met à jour une entité (Compatibilité)
     */
    @Transactional
    public T update(T entity) {
        return entityManager.merge(entity);
    }

    /**
     * Supprime une entité.
     */
    @Override
    @Transactional
    public void delete(T entity) {
        if (entity != null) {
            entityManager.remove(entityManager.contains(entity) ? entity : entityManager.merge(entity));
        }
    }

    /**
     * Supprime une entité par son UUID.
     */
    @Override
    @Transactional
    public boolean deleteById(UUID id) {
        T entity = findById(id);
        if (entity != null) {
            delete(entity);
            return true;
        }
        return false;
    }

    /**
     * Liste toutes les entités.
     */
    @Override
    public List<T> listAll() {
        return findAll().list();
    }

    /**
     * Liste toutes les entités avec pagination et tri (Compatibilité)
     */
    public List<T> findAll(io.quarkus.panache.common.Page page, io.quarkus.panache.common.Sort sort) {
        io.quarkus.hibernate.orm.panache.PanacheQuery<T> query;
        if (sort == null) {
            query = findAll();
        } else {
            query = findAll(sort);
        }
        return query.page(page).list();
    }

    /**
     * Compte toutes les entités.
     */
    @Override
    public long count() {
        return findAll().count();
    }

    /**
     * Vérifie si une entité existe par son UUID.
     */
    public boolean existsById(UUID id) {
        return findById(id) != null;
    }

    /**
     * Obtient l'EntityManager.
     */
    @Override
    public EntityManager getEntityManager() {
        return entityManager;
    }
}
