package com.ffii.fpsms.modules.user.entity;

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

import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import com.ffii.core.support.AbstractRepository;
import com.ffii.fpsms.modules.user.entity.projections.UserCombo;

public interface UserRepository extends AbstractRepository<User, Long> {

  List<User> findByName(@Param("name") String name);
  
  Optional<User> findByUsernameAndDeletedFalse(String username);

  List<UserCombo> findUserComboByTitleNotNullAndDepartmentNotNullAndNameNotNullAndDeletedFalse();

  Optional<User> findByStaffNo(@Param("staffNo") String staffNo);

  @Modifying
    @Query(value = """
        INSERT INTO user_authority (userID, authId)
        SELECT :userId, a.id
        FROM authority a
        WHERE a.authority = :code
        AND NOT EXISTS (
            SELECT 1
            FROM user_authority ua
            WHERE ua.userID = :userId
              AND ua.authId = a.id
        )
        LIMIT 1
    """, nativeQuery = true)
    void assignAuthorityByCodeIfNotExists(
        @Param("userId") Long userId,
        @Param("code") String code
    );

    // Optional: batch version (if you want to assign many at once)
    @Modifying
    @Query(value = """
        INSERT INTO user_authority (userID, authId)
        SELECT :userId, a.id
        FROM authority a
        WHERE a.authority IN :codes
        AND NOT EXISTS (
            SELECT 1
            FROM user_authority ua
            WHERE ua.userID = :userId
              AND ua.authId = a.id
        )
    """, nativeQuery = true)
    void assignAuthoritiesByCodesIfNotExists(
        @Param("userId") Long userId,
        @Param("codes") List<String> codes
    );
}
