package com.mvrent.carrental.service;

import com.mvrent.carrental.model.Role;
import com.mvrent.carrental.model.User;
import com.mvrent.carrental.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;

/**
 * Resolves a Google (OAuth2) sign-in to a local {@link User}. First-time Google
 * users are provisioned as CUSTOMER accounts; returning users are matched by email.
 * Admins are intentionally NOT created here — admin access stays on /admin/login.
 */
@Service
@RequiredArgsConstructor
public class OAuth2LoginService extends DefaultOAuth2UserService {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    @Override
    public OAuth2User loadUser(OAuth2UserRequest request) throws OAuth2AuthenticationException {
        OAuth2User oAuth2User = super.loadUser(request);

        String email = oAuth2User.getAttribute("email");
        String name = oAuth2User.getAttribute("name");
        if (email == null || email.isBlank()) {
            throw new OAuth2AuthenticationException("Google account has no email");
        }

        User user = userRepository.findByEmail(email).orElseGet(() -> provision(email, name));

        return new DefaultOAuth2User(
                List.of(new SimpleGrantedAuthority("ROLE_" + user.getRole().name())),
                oAuth2User.getAttributes(),
                "email"
        );
    }

    private User provision(String email, String name) {
        String base = email.substring(0, email.indexOf('@')).replaceAll("[^a-zA-Z0-9._-]", "");
        String username = base;
        int i = 1;
        while (userRepository.existsByUsername(username)) {
            username = base + i++;
        }
        User user = User.builder()
                .username(username)
                .email(email)
                .fullName(name != null && !name.isBlank() ? name : base)
                // random un-guessable password — these users sign in via Google only
                .password(passwordEncoder.encode(UUID.randomUUID().toString()))
                .role(Role.CUSTOMER)
                .enabled(true)
                .build();
        return userRepository.save(user);
    }
}
