package de.assecutor.votianlt.security.totp;

import de.assecutor.votianlt.model.User;
import de.assecutor.votianlt.repository.UserRepository;
import de.assecutor.votianlt.service.EmailService;
import org.springframework.stereotype.Service;

import java.security.SecureRandom;
import java.time.LocalDateTime;
import java.util.Optional;

@Service
public class TwoFactorService {

    private final UserRepository userRepository;
    private final EmailService emailService;
    private final SecureRandom random = new SecureRandom();

    public TwoFactorService(UserRepository userRepository, EmailService emailService) {
        this.userRepository = userRepository;
        this.emailService = emailService;
    }

    public void initiateTwoFactorFor(String email) {
        Optional<User> userOpt = userRepository.findByEmail(email);
        if (userOpt.isEmpty())
            return;
        User user = userOpt.get();
        String code = generateSixDigitCode();
        user.setPasswordCode(code);
        user.setPasswordTimestamp(LocalDateTime.now());
        userRepository.save(user);
        try {
            emailService.sendSimpleEmail(email, "Ihr Anmeldecode (2FA)",
                    "Ihr 2FA-Code lautet: " + code + "\nGültig für 10 Minuten.");
        } catch (Exception ignored) {
        }
    }

    public boolean verifyTwoFactorCode(String email, String code) {
        Optional<User> userOpt = userRepository.findByEmail(email);
        if (userOpt.isEmpty())
            return false;
        User user = userOpt.get();
        if (user.getPasswordCode() == null || !user.getPasswordCode().equals(code))
            return false;
        if (user.getPasswordTimestamp() == null)
            return false;
        // Gültigkeit 10 Minuten
        if (user.getPasswordTimestamp().isBefore(LocalDateTime.now().minusMinutes(10)))
            return false;
        // Code verbrauchen
        user.setPasswordCode(null);
        user.setPasswordTimestamp(null);
        userRepository.save(user);
        return true;
    }

    private String generateSixDigitCode() {
        int n = random.nextInt(1_000_000); // 0..999999
        return String.format("%06d", n);
    }
}
