package org.raddatz.familienarchiv.user;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.raddatz.familienarchiv.user.AppUser;
import org.raddatz.familienarchiv.user.AppUserRepository;
import org.raddatz.familienarchiv.security.Permission;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
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 java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class CustomUserDetailsService implements UserDetailsService {

    private static final Set<String> KNOWN_PERMISSIONS = Arrays.stream(Permission.values())
            .map(Enum::name)
            .collect(Collectors.toSet());

    private final AppUserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        AppUser appUser = userRepository.findByEmail(email)
                .orElseThrow(() -> new UsernameNotFoundException("User nicht gefunden: " + email));

        var authorities = appUser.getGroups().stream()
                .flatMap(group -> group.getPermissions().stream())
                .peek(p -> {
                    if (!KNOWN_PERMISSIONS.contains(p)) {
                        log.warn("Unknown permission '{}' found in database for user '{}' — it will be granted but never matched by @RequirePermission", p, appUser.getEmail());
                    }
                })
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toSet());

        return new User(
                appUser.getEmail(),
                appUser.getPassword(),
                appUser.isEnabled(),
                true, true, true,
                authorities
        );
    }
}