package dev.lions.unionflow.server.repository;

import dev.lions.unionflow.server.entity.Role;
import io.quarkus.hibernate.orm.panache.PanacheRepositoryBase;
import io.quarkus.panache.common.Sort;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

/**
 * Repository pour l'entité Role
 *
 * @author UnionFlow Team
 * @version 3.0
 * @since 2025-01-29
 */
@ApplicationScoped
public class RoleRepository implements PanacheRepositoryBase<Role, UUID> {

  /**
   * Trouve un rôle par son UUID
   *
   * @param id UUID du rôle
   * @return Rôle ou Optional.empty()
   */
  public Optional<Role> findRoleById(UUID id) {
    return find("id = ?1 AND actif = true", id).firstResultOptional();
  }

  /**
   * Trouve un rôle par son code
   *
   * @param code Code du rôle
   * @return Rôle ou Optional.empty()
   */
  public Optional<Role> findByCode(String code) {
    return find("code", code).firstResultOptional();
  }

  /**
   * Trouve tous les rôles système
   *
   * @return Liste des rôles système
   */
  public List<Role> findRolesSysteme() {
    return find("typeRole = ?1 AND actif = true", Sort.by("niveauHierarchique", Sort.Direction.Ascending),
        Role.TypeRole.SYSTEME.name())
        .list();
  }

  /**
   * Trouve tous les rôles d'une organisation
   *
   * @param organisationId ID de l'organisation
   * @return Liste des rôles
   */
  public List<Role> findByOrganisationId(UUID organisationId) {
    return find("organisation.id = ?1 AND actif = true", Sort.by("niveauHierarchique", Sort.Direction.Ascending),
        organisationId)
        .list();
  }

  /**
   * Trouve tous les rôles actifs
   *
   * @return Liste des rôles actifs
   */
  public List<Role> findAllActifs() {
    return find("actif = true", Sort.by("niveauHierarchique", Sort.Direction.Ascending)).list();
  }

  /**
   * Trouve les rôles par type
   *
   * @param typeRole Type de rôle (SYSTEME, ORGANISATION, PERSONNALISE)
   * @return Liste des rôles
   */
  public List<Role> findByType(String typeRole) {
    return find("typeRole = ?1 AND actif = true", Sort.by("niveauHierarchique", Sort.Direction.Ascending), typeRole)
        .list();
  }

  /**
   * Trouve les rôles par catégorie (PLATEFORME, FONCTIONNEL, METIER)
   *
   * @param categorie Catégorie du rôle
   * @return Liste des rôles actifs de cette catégorie
   */
  public List<Role> findByCategorie(String categorie) {
    return find("categorie = ?1 AND actif = true", Sort.by("niveauHierarchique", Sort.Direction.Ascending), categorie)
        .list();
  }

  /**
   * Trouve les rôles plateforme (SUPERADMIN, ORGADMIN, etc.)
   *
   * @return Liste des rôles plateforme actifs
   */
  public List<Role> findRolesPlateformeActifs() {
    return findByCategorie("PLATEFORME");
  }

  /**
   * Trouve les rôles fonctionnels et métier (assignables dans une org)
   *
   * @return Liste des rôles assignables
   */
  public List<Role> findRolesAssignables() {
    return find("categorie IN ('FONCTIONNEL', 'METIER') AND actif = true",
        Sort.by("niveauHierarchique", Sort.Direction.Ascending))
        .list();
  }
}
