package fr.eni.enchere.controllers;

import fr.eni.enchere.bll.ForgotPasswordService;
import fr.eni.enchere.bll.UserService;
import fr.eni.enchere.bo.ForgotPassword;
import fr.eni.enchere.bo.UserProfil;
import org.apache.commons.validator.routines.EmailValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Calendar;
import java.util.regex.Pattern;

@Controller()
@RequestMapping("/forgotPassword")
public class ForgotPasswordController {

    @Autowired
    private final UserService userService;
    private EmailValidator emailValidator;
    private ForgotPasswordService forgotPasswordService;

    public ForgotPasswordController(EmailValidator emailValidator, ForgotPasswordService forgotPasswordService, UserService userService) {
        this.userService = userService;
        this.emailValidator = emailValidator;
        this.forgotPasswordService = forgotPasswordService;
    }

    @GetMapping
    public String forgotPassword(Model model, @RequestParam(value = "link", required = false) String link) {
        // Vérifier si l'utilisateur est déjà authentifié
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (!authentication.getName().equals("anonymousUser")){
            return "redirect:/enchere";
        }
        if (link != null) {
            ForgotPassword forgotPassword = forgotPasswordService.getForgotPassword(link);
            if (forgotPassword != null) {
                Calendar dateNow = Calendar.getInstance();
                if (dateNow.before(forgotPassword.getDateExpire())){
                    return "redirect:/forgotPassword/changePassword?link=" + forgotPassword.getLink();
                }else{
                    return "redirect:/forgotPassword/changePasswordExpired?link=" + forgotPassword.getLink();
                }
            }else{
                return "redirect:/security/forgotPassword";
            }
        }else{
            return "security/forgotPassword";
        }
    }

    @PostMapping
    public String createLinkForgotPassword(@RequestParam("email") String email) {
        if (email.isEmpty()){
            return "redirect:/forgotPassword?error";
        }else{
            if (!emailValidator.isValid(email)) {
                return "redirect:/forgotPassword?error";
            }
        }
        //Vérification de l'email dans la base de donnée
        if (userService.getUserByMail(email) == null){
            return "redirect:/forgotPassword?error";
        }
        forgotPasswordService.setForgotPassword(email);
        return "redirect:/forgotPassword?mailSend";
    }

    @GetMapping("/changePassword")
    public String forgotPasswordChangePassword(Model model, @RequestParam(value = "link", required = true) String link) {
        // Vérifier si l'utilisateur est déjà authentifié
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (!authentication.getName().equals("anonymousUser")){
            return "redirect:/enchere";
        }
        ForgotPassword forgotPassword = forgotPasswordService.getForgotPassword(link);
        if (forgotPassword != null) {
            Calendar dateNow = Calendar.getInstance();
            if (dateNow.before(forgotPassword.getDateExpire())){
                return "security/changePassword";
            }else{
                return "redirect:/forgotPassword/changePasswordExpired?link=" + forgotPassword.getLink();
            }
        }else{
            return "security/forgotPassword";
        }
    }

    @PostMapping("/changePassword/check")
    public String changePassword(@RequestParam("email") String email,
                                 @RequestParam("password") String password,
                                 @RequestParam("confirmPassword") String confirmPassword,
                                 @RequestParam("link") String link) {
        ForgotPassword forgotPassword = forgotPasswordService.getForgotPassword(link);
        if (forgotPassword != null) {
            Calendar dateNow = Calendar.getInstance();
            if (dateNow.before(forgotPassword.getDateExpire())){
                if (email.equalsIgnoreCase(forgotPassword.getEmail())){
                    if (password.equals(confirmPassword)){
                        String passwordRegex = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@?*#$%^&+=_!\\-])(?=\\S+$).{8,}$";
                        Pattern pattern = Pattern.compile(passwordRegex);
                        // Vérifier si le mot de passe correspond à l'expression régulière
                        if (pattern.matcher(password).matches()){
                            UserProfil userForgotPassword = userService.utilisateurByEmail(email);
                            userForgotPassword.setNewPassword(password);
                            userService.setUtilisateur(userForgotPassword);
                            return "redirect:/login";
                        }else{
                            return "redirect:/forgotPassword/changePassword?link=" + forgotPassword.getLink() + "&passwordSecurity";
                        }
                    }else{
                        return "redirect:/forgotPassword/changePassword?link=" + forgotPassword.getLink() + "&passwordNotIdentique";
                    }
                }else{
                    return "redirect:/forgotPassword/changePassword?link=" + forgotPassword.getLink() + "&emailError";
                }
            }else{
                return "redirect:/forgotPassword/changePasswordExpired?link=" + forgotPassword.getLink();
            }
        }else{
            return "security/forgotPassword";
        }
    }

    @GetMapping("/changePasswordExpired")
    public String forgotPasswordLinkExpired(Model model, @RequestParam(value = "link", required = true) String link) {
        // Vérifier si l'utilisateur est déjà authentifié
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (!authentication.getName().equals("anonymousUser")){
            return "redirect:/enchere";
        }
        ForgotPassword forgotPassword = forgotPasswordService.getForgotPassword(link);
        if (forgotPassword != null) {
            Calendar dateNow = Calendar.getInstance();
            if (dateNow.before(forgotPassword.getDateExpire())){
                return "redirect:/forgotPassword/changePassword?link=" + forgotPassword.getLink();
            }else{
                return "security/changePasswordExpired";
            }
        }else{
            return "security/forgotPassword";
        }
    }

}
