package com.qqchen.deploy.backend.system.service.impl;

import com.qqchen.deploy.backend.framework.security.CustomUserDetails;
import com.qqchen.deploy.backend.system.entity.User;
import com.qqchen.deploy.backend.system.repository.IPermissionRepository;
import com.qqchen.deploy.backend.system.repository.IUserRepository;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.Hibernate;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户详情服务实现
 * 负责从数据库加载用户信息并转换为 Spring Security 的 UserDetails
 *
 * @author qqchen
 * @date 2025-10-25
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {

    @Resource
    private final IUserRepository userRepository;
    
    @Resource
    private final IPermissionRepository permissionRepository;

    @Override
    @Transactional(readOnly = true)
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsernameAndDeletedFalse(username)
                .orElseThrow(() -> new UsernameNotFoundException("用户不存在: " + username));
        
        // ✅ 批量加载用户权限(避免N+1查询)
        Hibernate.initialize(user.getRoles());  // 加载角色
        
        // 检查用户是否是超级管理员（拥有 is_admin=true 的角色）
        boolean isAdmin = user.getRoles().stream()
            .anyMatch(role -> Boolean.TRUE.equals(role.getIsAdmin()));
        
        List<SimpleGrantedAuthority> authorities = new java.util.ArrayList<>();
        
        // 1. 加载角色本身（用于hasRole判断）
        user.getRoles().stream()
            .map(role -> new SimpleGrantedAuthority(role.getCode()))
            .forEach(authorities::add);
        
        // 2. 加载权限点（用于hasAuthority判断）
        List<Long> roleIds = user.getRoles().stream()
            .map(role -> role.getId())
            .collect(Collectors.toList());
        
        if (!roleIds.isEmpty()) {
            permissionRepository.findByRoleIds(roleIds).stream()
            .map(permission -> new SimpleGrantedAuthority(permission.getCode()))
            .distinct()
                .forEach(authorities::add);
        }
        
//        log.debug("加载用户 {} 的权限: {} 个角色{}, {} 个权限点", username, user.getRoles().size(), isAdmin ? "(超级管理员)" : "", authorities.size() - user.getRoles().size());
        
        // 返回自定义 UserDetails,包含用户ID等扩展信息
        return new CustomUserDetails(
                user.getId(),                // 用户ID
                user.getUsername(),          // 用户名
                user.getPassword(),          // 密码
                user.getEnabled(),           // 是否启用
                authorities                  // 实际权限
        );
    }
}
