package com.imprimelibros.erp.users;

import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

@Repository
public interface UserDao extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {

    // Aplicamos EntityGraph a la versión con Specification+Pageable
    @Override
    @EntityGraph(attributePaths = { "rolesLink", "rolesLink.role" })
    @NonNull
    Page<User> findAll(@Nullable Specification<User> spec, @NonNull Pageable pageable);

    Optional<User> findByUserNameIgnoreCase(String userName);

    boolean existsByUserNameIgnoreCase(String userName);

    // Para comprobar si existe al hacer signup
    @Query(value = """
            SELECT id, deleted, enabled
            FROM users
            WHERE LOWER(username) = LOWER(:userName)
            LIMIT 1
            """, nativeQuery = true)
    Optional<UserLite> findLiteByUserNameIgnoreCase(@Param("userName") String userName);

    boolean existsByUserNameIgnoreCaseAndIdNot(String userName, Long id);

    // Nuevo: para login/negocio "activo"
    @EntityGraph(attributePaths = { "rolesLink", "rolesLink.role" })
    Optional<User> findByUserNameIgnoreCaseAndEnabledTrueAndDeletedFalse(String userName);

    // Para poder restaurar, necesitas leer ignorando @Where (native):
    @Query(value = "SELECT * FROM users WHERE id = :id", nativeQuery = true)
    Optional<User> findByIdIncludingDeleted(@Param("id") Long id);

    @Query(value = "SELECT * FROM users WHERE deleted = TRUE", nativeQuery = true)
    List<User> findAllDeleted();

    @Query("select u.id from User u where lower(u.userName) = lower(:userName)")
    Optional<Long> findIdByUserNameIgnoreCase(@Param("userName") String userName);

}
