package de.oaa.xxx.passwordreset;

import de.oaa.xxx.mail.Email;
import de.oaa.xxx.mail.MailService;
import de.oaa.xxx.mail.MailTemplateService;
import de.oaa.xxx.user.UserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.UUID;

@RestController
@RequestMapping("/password-reset")
public class PasswordResetController {

    private static final Logger LOGGER = LoggerFactory.getLogger(PasswordResetController.class);

    @Value("${app.base-url:http://localhost:8080}")
    private String baseUrl;

    private final PasswordResetRepository passwordResetRepository;
    private final UserRepository userRepository;
    private final MailService mailService;
    private final MailTemplateService mailTemplateService;
    private final PasswordEncoder passwordEncoder;

    public PasswordResetController(PasswordResetRepository passwordResetRepository,
                                   UserRepository userRepository,
                                   MailService mailService,
                                   MailTemplateService mailTemplateService,
                                   PasswordEncoder passwordEncoder) {
        this.passwordResetRepository = passwordResetRepository;
        this.userRepository = userRepository;
        this.mailService = mailService;
        this.mailTemplateService = mailTemplateService;
        this.passwordEncoder = passwordEncoder;
    }

    @PostMapping("/request")
    public ResponseEntity<Void> request(@RequestBody PasswordResetRequest request) {
        userRepository.findByEmail(request.email()).ifPresent(user -> {
            passwordResetRepository.findByEmail(request.email())
                    .ifPresent(passwordResetRepository::delete);
            PasswordResetEntity entity = PasswordResetEntity.create(request.email());
            passwordResetRepository.save(entity);
            String resetLink = baseUrl + "/reset-password.html?token=" + entity.getTokenId();
            Email email = new Email();
            email.setTitel("Passwort zurücksetzen");
            email.setEmailAdresse(request.email());
            email.setText(mailTemplateService.buildPasswordResetMail(user.getName(), resetLink));
            mailService.send(email);
            LOGGER.info("Passwort-Reset angefordert für: {}", request.email());
        });
        return ResponseEntity.status(202).build();
    }

    @PostMapping("/confirm")
    public ResponseEntity<Void> confirm(@RequestBody PasswordResetConfirm confirm) {
        UUID tokenId;
        try {
            tokenId = UUID.fromString(confirm.token());
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().build();
        }
        var entity = passwordResetRepository.findById(tokenId);
        if (entity.isEmpty()) {
            return ResponseEntity.badRequest().build();
        }
        userRepository.findByEmail(entity.get().getEmail()).ifPresent(user -> {
            user.setPassword(passwordEncoder.encode(confirm.password()));
            userRepository.save(user);
            LOGGER.info("Passwort zurückgesetzt für: {}", entity.get().getEmail());
        });
        passwordResetRepository.delete(entity.get());
        return ResponseEntity.ok().build();
    }
}
