package fr.eni.enchere.controllers;

import fr.eni.enchere.bll.ArticleService;
import fr.eni.enchere.bll.BankService;
import fr.eni.enchere.bll.UserService;
import fr.eni.enchere.bo.Bank;
import fr.eni.enchere.bo.UserProfil;
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.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

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

@Controller()
@RequestMapping("/bank")
public class BankController {

    @Autowired
    private final UserService userService;
    private BankService bankService;

    public BankController(UserService userService, BankService bankService) {
        this.userService = userService;
        this.bankService = bankService;
    }

    @GetMapping
    public String home() {
        return "redirect:/bank/home";
    }

    @GetMapping("/home")
    public String homeCredit(Model model) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication.getName().equals("anonymousUser")){
            return "redirect:/enchere";
        }
        model.addAttribute("bank", new Bank());
        return "bank";
    }

    @PostMapping("/checkout")
    public String addCreditCheckout(@ModelAttribute("bank") Bank infoBank, BindingResult result) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication.getName().equals("anonymousUser")){
            return "redirect:/accueil";
        }
        String username = authentication.getName();
        UserProfil userProfile = userService.utilisateurByName(username);
        //Vérification du prix demmander
        if (infoBank.getCartAmount() > 2000000.0 || infoBank.getCartAmount() < 1.0){
            result.rejectValue("cartAmount", "error.bank", "Le prix demander est incorrect.");
        }
        //Vérification du numéro de la carte
        // Expression régulière pour vérifier si la variable contient exactement 16 chiffres
        if (!Pattern.matches("^\\d{16}$", infoBank.getCartNumber())){
            result.rejectValue("cartNumber", "error.bank", "Le numéro de la carte est invalide.");
        }
        //Vérification de la date d'expiration de la carte
        if (!Pattern.matches("^(0[1-9]|1[0-2])/(1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|6[0-9]|7[0-9]|8[0-9]|9[0-9]|[0-9]{2,3})\\d{2}$", infoBank.getCartExpired())){
            result.rejectValue("cartExpired", "error.bank", "La date d'expiration est incorrecte.");
        }else{
            Calendar calendar = Calendar.getInstance();
            int moisNow = calendar.get(Calendar.MONTH) + 1;
            int anneeNow = calendar.get(Calendar.YEAR);
            String[] parts = infoBank.getCartExpired().split("/");
            int mois = Integer.parseInt(parts[0]);
            int annee = Integer.parseInt(parts[1]);
            if (annee < anneeNow){
                result.rejectValue("cartExpired", "error.bank", "Votre carte est expiré.");
            }
            if(annee == anneeNow && mois < moisNow){
                result.rejectValue("cartExpired", "error.bank", "Votre carte est expiré.");
            }
        }
        //Vérification de du CVV de la carte
        if (!Pattern.matches("^\\d{3}$", String.valueOf(infoBank.getCartCVV()))){
            result.rejectValue("cartCVV", "error.bank", "Le CVV est incorrect.");
        }
        //Vérification du nom de la carte
        if (infoBank.getCartName().isEmpty()){
            result.rejectValue("cartName", "error.bank", "Le titulaire de la carte est obligatoire.");
        }
        //Passer au payement
        Bank bank = bankService.isValideCart(infoBank.getCartNumber(), infoBank.getCartExpired(), infoBank.getCartCVV());
        if (bank == null){
            result.rejectValue("cartName", "error.bank", "Votre paiement n'a pas aboutie.");
        }
        if (result.hasErrors()) {
            return "bank";
        }
        if (infoBank.getCartAmount() > bank.getCartAmount()){
            return "bankDeny";
        }
        bankService.setCredit(bank, bank.getCartAmount()-infoBank.getCartAmount());
        userService.setCredit(userProfile.getCredit()+infoBank.getCartAmount(), userProfile.getId());
        return "bankAllow";
    }

}
