package zw.qantra.tm.domain.services; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import zw.qantra.tm.domain.dtos.AuthResponse; import zw.qantra.tm.domain.dtos.LoginRequest; import zw.qantra.tm.domain.dtos.RegisterRequest; import zw.qantra.tm.domain.models.User; import zw.qantra.tm.domain.repositories.UserRepository; import zw.qantra.tm.utils.JwtUtils; @Service @RequiredArgsConstructor public class UserService implements UserDetailsService { @Getter private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; private final JwtUtils jwtUtils; private final TransactionService transactionService; public User fetchUserByUsername(String username) { return userRepository.findByUsername(username) .orElseThrow(() -> new UsernameNotFoundException("User not found with username: " + username)); } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { return userRepository.findByUsername(username) .orElseThrow(() -> new UsernameNotFoundException("User not found with username: " + username)); } public AuthResponse register(RegisterRequest request) { if (userRepository.existsByUsername(request.getUsername())) { throw new RuntimeException("Username already exists"); } if (userRepository.existsByEmail(request.getEmail())) { throw new RuntimeException("Email already exists"); } User user = new User(); user.setUsername(request.getUsername()); user.setPassword(passwordEncoder.encode(request.getPassword())); user.setEmail(request.getEmail()); user.setFirstName(request.getFirstName()); user.setLastName(request.getLastName()); user.setPhone(request.getPhone()); user.setWorkflowId(request.getWorkflowId()); user.setPhotoUrl(request.getPhotoUrl()); user.setDeleted(false); User savedUser = userRepository.save(user); String token = jwtUtils.generateToken(savedUser); // reassign anonymous transactions to the new user // if we fail we move on, not a critical step try { transactionService.reassignTransactions(request.getTempUid(), savedUser.getId().toString()); }catch (Exception e) { e.printStackTrace(); } return new AuthResponse(token, "Bearer", savedUser.getUsername(), savedUser.getEmail(), savedUser.getPhone(), savedUser.getFirstName(), savedUser.getLastName(), savedUser.getId()); } public AuthResponse login(LoginRequest request) { User user = userRepository.findByUsername(request.getUsername()) .orElseThrow(() -> new RuntimeException("Invalid username or password")); if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) { throw new RuntimeException("Invalid username or password"); } String token = jwtUtils.generateToken(user); return new AuthResponse(token, "Bearer", user.getUsername(), user.getEmail(), user.getPhone(), user.getFirstName(), user.getLastName(), user.getId()); } }