package com.saas.admin.repository;

import com.saas.admin.entity.Role;
import com.saas.admin.entity.User;
import com.saas.admin.entity.UserRole;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

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

/**
 * Repository for UserRole junction table
 */
@Repository
public interface UserRoleRepository extends JpaRepository<UserRole, Long> {
    
    /**
     * Find all roles for a user
     */
    List<UserRole> findByUser(User user);
    
    /**
     * Find all roles for a user by user ID
     */
    @Query("SELECT ur FROM UserRole ur JOIN FETCH ur.role WHERE ur.user.id = :userId")
    List<UserRole> findByUserIdWithRoles(@Param("userId") Long userId);
    
    /**
     * Find all users who have a specific role
     */
    List<UserRole> findByRole(Role role);
    
    /**
     * Find specific user-role mapping
     */
    Optional<UserRole> findByUserAndRole(User user, Role role);
    
    /**
     * Check if user has specific role
     */
    boolean existsByUserAndRole(User user, Role role);
    
    /**
     * Delete all roles for a user
     */
    void deleteByUser(User user);
    
    /**
     * Delete all users who have a specific role
     */
    void deleteByRole(Role role);
    
    /**
     * Get all permissions for a user (aggregated from all their roles)
     * Returns permission strings: ["tenant:read", "tenant:write", ...]
     */
    @Query("SELECT DISTINCT CONCAT(p.resource, ':', p.action) " +
           "FROM UserRole ur " +
           "JOIN ur.role r " +
           "JOIN r.rolePermissions rp " +
           "JOIN rp.permission p " +
           "WHERE ur.user = :user AND r.isActive = true AND p.isActive = true")
    List<String> findAllPermissionsByUser(@Param("user") User user);
    
    /**
     * Get all permissions for a user by user ID
     */
    @Query("SELECT DISTINCT CONCAT(p.resource, ':', p.action) " +
           "FROM UserRole ur " +
           "JOIN ur.role r " +
           "JOIN r.rolePermissions rp " +
           "JOIN rp.permission p " +
           "WHERE ur.user.id = :userId AND r.isActive = true AND p.isActive = true")
    List<String> findAllPermissionsByUserId(@Param("userId") Long userId);
    
    /**
     * Count users who have a specific role
     */
    long countByRole(Role role);
}
