package com.jwt.restapi.controller;

import com.jwt.restapi.entity.User;
import com.jwt.restapi.repository.UserRepository;
import com.jwt.restapi.security.JwtTokenProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;

@RestController
@RequestMapping("/auth")
public class AuthController {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    // Register a new user
    @PostMapping("/register")
    public ResponseEntity<?> register(@RequestBody User user) {
        if (userRepository.existsByUsername(user.getUsername())) {
            return ResponseEntity.badRequest().body("Username already taken");
        }
        if (!user.getPassword().equals(user.getPasswordRepeat())) {
            return ResponseEntity.badRequest().body("Passwords do not match");
        }

        // If role is provided as 'ADMIN', store 'ADMIN'; otherwise, store 'USER' (default)
        if (user.getRole() == null || user.getRole().toString().isEmpty() ||user.toString().isBlank()|| user.getRole() != User.Role.ADMIN) {
            user.setRole(User.Role.USER);  // Default to 'USER' if role is not 'ADMIN'
        }

        // Encrypt the password before saving
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));

        // Encrypt the passwordRepeat (if needed, though it won't be saved in DB)
        user.setPasswordRepeat(null); // Clear passwordRepeat to avoid saving it

        // Save the user to the repository
        userRepository.save(user);

        return ResponseEntity.ok("User registered successfully");
    }

    // Login a user and generate JWT token
    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody User user) {
        User foundUser = userRepository.findByUsername(user.getUsername());

        if (foundUser == null || !bCryptPasswordEncoder.matches(user.getPassword(), foundUser.getPassword())) {
            return ResponseEntity.badRequest().body("Invalid credentials");
        }

        // Dynamically assign the user's role to the JWT token
        SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_" + foundUser.getRole().name());

        // Generate the token
        String token = jwtTokenProvider.generateToken(foundUser.getUsername(),
                Collections.singletonList(authority));

        return ResponseEntity.ok("Bearer " + token);
    }
}
