package com.hpay.hpay_mobile_api.services;

import com.hpay.hpay_mobile_api.DTO.CarteClientQrDTO;
import com.hpay.hpay_mobile_api.DTO.ErrorResponse;
import com.hpay.hpay_mobile_api.DTO.SuccessResponse;
import com.hpay.hpay_mobile_api.entities.*;
import com.hpay.hpay_mobile_api.repositories.CarteClientQrRepository;
import com.hpay.hpay_mobile_api.repositories.CarteGenereeRepository;
import com.hpay.hpay_mobile_api.repositories.CompteRepository;
import com.hpay.hpay_mobile_api.repositories.LoginClientRepository;
import com.hpay.hpay_mobile_api.repositories.HistoriqueCartesRepository;
import com.hpay.hpay_mobile_api.utils.SMSapi;
import com.hpay.hpay_mobile_api.utils.SendEmail;
import com.hpay.hpay_mobile_api.utils.SendEmailAddCard;
import jakarta.mail.MessagingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Optional;

@Service
public class CarteClientQrService {

    @Autowired
    private CarteClientQrRepository carteClientQrRepository;

    @Autowired
    private CompteRepository compteRepository;

    @Autowired
    CarteGenereeRepository carteGenereeRepository;

    @Autowired
    private LoginClientRepository loginClientRepository;

    @Autowired
    private HistoriqueCartesRepository historiqueCartesRepository;

    public Object  ajouterCarteAuCompte(Long idCompte, Long idLoginClient, CarteClientQrDTO carteClientQrDTO) {

        LoginClient loginClient = loginClientRepository.findById(idLoginClient).orElse(null);;

        if (loginClient == null ) {
            return new ErrorResponse("client not found", 401);  // Invalid login response
        }

        if (!loginClient.getClient().getValider().equals("1") ) {
            return new ErrorResponse("client not validate", 401);  // Invalid login response
        }


        // Récupérer le compte par ID
        Compte compte = compteRepository.findById(idCompte).orElse(null);

        //verification si le compte existe
        if (compte == null) {
            return new ErrorResponse("Account not found", 404);
        }


        Optional<CarteGeneree> carteOptional = carteGenereeRepository.findByNumCarte(carteClientQrDTO.getNumCarte());


        // verification si la carte existe
        if (carteOptional.isEmpty()) {
            return new ErrorResponse("Card not found", 404);
        }

        CarteGeneree carte= carteOptional.get();

        // verification si la carte est encore valide
        Date currentDate = new Date();
        if(!carte.getDateValidite().after(currentDate)){
            return new ErrorResponse("Card expired", 404);
        }

        // verification que la carte n'est pas utilisée
        //System.out.print(carte.getUtilisee());
        if(carte.getUtilisee()){
            return new ErrorResponse("Card Dejà utilisé", 404);
        }


        // verification du code pin de la carte
        if( !carte.getPin().equals(carteClientQrDTO.getPin()) ){
            return new ErrorResponse("not valid code pin", 404);
        }

        // verification si une carte est dejà lié au compte
        if(compte.getCarteClientQr()!=null){
            return new ErrorResponse("Card already linked", 404);
        }


        // Créer une nouvelle carte à partir du DTO
        CarteClientQr carteClientQr = new CarteClientQr();
        carteClientQr.setNumCarte(carteClientQrDTO.getNumCarte());
        carteClientQr.setFrais(carteClientQrDTO.getFrais());
        carteClientQr.setDateCreation(carte.getDateGeneration());
        carteClientQr.setDateExpire(carte.getDateValidite());
        carteClientQr.setPin(carteClientQrDTO.getPin());
        carteClientQr.setTypeCarte(carteClientQrDTO.getTypeCarte());
        carteClientQr.setIdAgence(carteClientQrDTO.getIdAgence());
        carteClientQr.setIdCommercial(carteClientQrDTO.getIdCommercial());
        carteClientQr.setIdGestionnaire(carteClientQrDTO.getIdGestionnaire());
        carteClientQr.setIdClients(carteClientQrDTO.getIdClients());
        carteClientQr.setActif("1");
        carteClientQr.setCompte(compte);  // Associer la carte au compte

        //creation d'un objet HistoriqueCartes
        HistoriqueCartes historiqueCartes = new HistoriqueCartes();
        historiqueCartes.setAction("Ajout");
        historiqueCartes.setDetails("Ajout de la carte pour le client.");
        historiqueCartes.setIp(carteClientQrDTO.getIp());
        historiqueCartes.setIdclients(loginClient.getClient().getId());
        historiqueCartes.setDateAction(LocalDateTime.now());
        historiqueCartes.setNumCarte(carteClientQr.getNumCarte());

        carte.setUtilisee(true);  // Mettre le champ 'utilisee' à true (1)
        carteGenereeRepository.save(carte);  // Sauvegarder la carte mise à jour

        // Sauvegarder de la liaison carte dans la base de données
        carteClientQr = carteClientQrRepository.save(carteClientQr);

        // sauvegarde de l'historique
        historiqueCartesRepository.save(historiqueCartes);

        // envois du sms
        SMSapi sms= new SMSapi();
        sms.alaSMS(loginClient.getClient().getPays().getIndicatif()  + loginClient.getLogin(),
                "Une carte de numéro "+carte.getNumCarte()+" a été ajoutée à votre compte. Si ce n'est pas vous, contactez le support."
        );


        // envois de l'email
        try {
            LocalDate currentDate1 = LocalDate.now();
            DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String formattedDate = currentDate1.format(formatter1);

            LocalTime currentTime = LocalTime.now();
            DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm");
            String formattedTime = currentTime.format(timeFormatter);

            SendEmail.sendEmailAddCard(
                    loginClient.getClient().getEmail(),
                    loginClient.getClient().getPrenoms(),
                    carte.getNumCarte(),
                    formattedDate,
                    formattedTime
            );


        }catch (MessagingException e) {
            e.printStackTrace();
        }



        HashMap<String, Object> map = new HashMap<>();
        map.put("data",carteClientQr);


        return new SuccessResponse("card succesffully added", 200, map );

    }




    public Object  modifyPinCompte(Long idCompte, Long idLoginClient,  CarteClientQrDTO carteClientQrDTO) {

        LoginClient loginClient = loginClientRepository.findById(idLoginClient).orElse(null);;

        if (loginClient == null ) {
            return new ErrorResponse("client not found", 401);  // Invalid login response
        }

        if (!loginClient.getClient().getValider().equals("1") ) {
            return new ErrorResponse("client not validate", 401);  // Invalid login response
        }



        // Récupérer le compte par ID
        Compte compte = compteRepository.findById(idCompte)
                .orElse(null);

        if (compte == null) {
            return new ErrorResponse("Account not found", 404);
        }


        CarteClientQr existingCardClientQr = compte.getCarteClientQr();

        if(existingCardClientQr == null){
            return new ErrorResponse("Card not exist", 404);
        }

        Optional<CarteGeneree> carteOptional = carteGenereeRepository.findByNumCarte(existingCardClientQr.getNumCarte());


        // verification si la carte existe
        if (carteOptional.isEmpty()) {
            return new ErrorResponse("Card not found", 404);
        }

        //update du pin dans carteGeneree
        CarteGeneree carte= carteOptional.get();
        carte.setPin(carteClientQrDTO.getPin());
        carteGenereeRepository.save(carte);

        //update du pin dans CardClientQr
        existingCardClientQr.setPin(carteClientQrDTO.getPin());
        existingCardClientQr.setCompte(compte);


        //creation d'un objet HistoriqueCartes
        HistoriqueCartes historiqueCartes = new HistoriqueCartes();
        historiqueCartes.setAction("Changement PIN");
        historiqueCartes.setDetails("Changement du code pin lié à la carte");
        historiqueCartes.setIp(carteClientQrDTO.getIp());
        historiqueCartes.setIdclients(loginClient.getClient().getId());
        historiqueCartes.setDateAction(LocalDateTime.now());
        historiqueCartes.setNumCarte(existingCardClientQr.getNumCarte());

        // sauvegarte l'objet CardClientQr
        existingCardClientQr = carteClientQrRepository.save(existingCardClientQr);

        // sauvegarde de l'historique
        historiqueCartesRepository.save(historiqueCartes);

        // envois du sms
        SMSapi sms= new SMSapi();
        sms.alaSMS(loginClient.getClient().getPays().getIndicatif()  + loginClient.getLogin(),
                "Le code PIN de votre carte HPay "+carte.getNumCarte()+" a été modifié avec succès"
        );


        // envois de l'email
        try {
            LocalDate currentDate1 = LocalDate.now();
            DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String formattedDate = currentDate1.format(formatter1);

            LocalTime currentTime = LocalTime.now();
            DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm");
            String formattedTime = currentTime.format(timeFormatter);

            SendEmail.sendEmailModifyPinCard(
                    loginClient.getClient().getEmail(),
                    loginClient.getClient().getPrenoms(),
                    carte.getNumCarte(),
                    formattedDate,
                    formattedTime
            );


        }catch (MessagingException e) {
            e.printStackTrace();
        }



        HashMap<String, Object> map = new HashMap<>();
        map.put("data",existingCardClientQr);
        return new SuccessResponse("Card succesffully added", 200, map );


    }



    public Object  removeCardCompte(Long idcarteClientQr,Long idLoginClient,CarteClientQrDTO carteClientQrDTO) {

        LoginClient loginClient = loginClientRepository.findById(idLoginClient).orElse(null);;

        if (loginClient == null ) {
            return new ErrorResponse("client not found", 401);  // Invalid login response
        }

        if (!loginClient.getClient().getValider().equals("1") ) {
            return new ErrorResponse("client not validate", 401);  // Invalid login response
        }


        // Récupérer le compte par ID
        CarteClientQr carteClientQr= carteClientQrRepository.findById(idcarteClientQr).orElse(null);

        if (carteClientQr== null) {
            return new ErrorResponse("card not found", 404);
        }


        Optional<CarteGeneree> carteOptional = carteGenereeRepository.findByNumCarte(carteClientQr.getNumCarte());


        // verification si la carte existe
        if (carteOptional.isEmpty()) {
            return new ErrorResponse("Card not found", 404);
        }

        //update du pin dans carteGeneree
        CarteGeneree carte= carteOptional.get();
        carte.setUtilisee(false);

        //creation d'un objet HistoriqueCartes
        HistoriqueCartes historiqueCartes = new HistoriqueCartes();
        historiqueCartes.setAction("Changement PIN");
        historiqueCartes.setDetails("Changement du code pin lié à la carte");
        historiqueCartes.setIp(carteClientQrDTO.getIp());
        historiqueCartes.setIdclients(loginClient.getClient().getId());
        historiqueCartes.setDateAction(LocalDateTime.now());
        historiqueCartes.setNumCarte(carteClientQr.getNumCarte());


        // sauvegarde de l'update de la carte
        carteClientQrRepository.deleteById(idcarteClientQr);

        // sauvegarde de l'update de la carte
        carteGenereeRepository.save(carte);

        // sauvegarde de l'historique
        historiqueCartesRepository.save(historiqueCartes);


        // envois du sms
        SMSapi sms= new SMSapi();
        sms.alaSMS(loginClient.getClient().getPays().getIndicatif()  + loginClient.getLogin(),
                "HPay : La carte HPay numéro "+carte.getNumCarte()+" a été retirée de votre compte. Si ce n'est pas vous, contactez le support."
        );

        // envois de l'email
        try {
            LocalDate currentDate1 = LocalDate.now();
            DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String formattedDate = currentDate1.format(formatter1);

            LocalTime currentTime = LocalTime.now();
            DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm");
            String formattedTime = currentTime.format(timeFormatter);

            SendEmail.sendEmailRemoveCard(
                    loginClient.getClient().getEmail(),
                    loginClient.getClient().getPrenoms(),
                    carte.getNumCarte(),
                    formattedDate,
                    formattedTime
            );


        }catch (MessagingException e) {
            e.printStackTrace();
        }

        HashMap<String, Object> map = new HashMap<>();
        map.put("data",null);
        return new SuccessResponse("Card succesffully deleted", 200, map );

    }



    public Object  toggleActiveCompte(Long idCompte, Long idLoginClient, CarteClientQrDTO carteClientQrDTO) {


        LoginClient loginClient = loginClientRepository.findById(idLoginClient).orElse(null);;

        if (loginClient == null ) {
            return new ErrorResponse("client not found", 401);  // Invalid login response
        }

        if (!loginClient.getClient().getValider().equals("1") ) {
            return new ErrorResponse("client not validate", 401);  // Invalid login response
        }


        // Récupérer le compte par ID
        Compte compte = compteRepository.findById(idCompte)
                .orElse(null);

        if (compte == null) {
            return new ErrorResponse("Account not found", 404);
        }


        CarteClientQr existingCardClientQr = compte.getCarteClientQr();

        if(existingCardClientQr == null){
            return new ErrorResponse("Card not exist", 404);
        }


        //update du pin dans CardClientQr
        if(existingCardClientQr.getActif().equals("1")){
            existingCardClientQr.setActif("0");
            existingCardClientQr.setCompte(compte);
            existingCardClientQr = carteClientQrRepository.save(existingCardClientQr);

            //creation d'un objet HistoriqueCartes
            HistoriqueCartes historiqueCartes = new HistoriqueCartes();
            historiqueCartes.setAction("Désactivation");
            historiqueCartes.setDetails("Désactivation  du code Pin");
            historiqueCartes.setIp(carteClientQrDTO.getIp());
            historiqueCartes.setIdclients(loginClient.getClient().getId());
            historiqueCartes.setDateAction(LocalDateTime.now());
            historiqueCartes.setNumCarte(existingCardClientQr.getNumCarte());
            historiqueCartesRepository.save(historiqueCartes);

            /*SMSapi sms= new SMSapi();
            sms.alaSMS(loginClient.getClient().getPays().getIndicatif()  + loginClient.getLogin(),
                    "Votre carte HPay "+existingCardClientQr.getNumCarte()+" a été désactivé avec succès"
            );*/

        }else{
            existingCardClientQr.setActif("1");
            existingCardClientQr.setCompte(compte);
            existingCardClientQr = carteClientQrRepository.save(existingCardClientQr);

            //creation d'un objet HistoriqueCartes
            HistoriqueCartes historiqueCartes = new HistoriqueCartes();
            historiqueCartes.setAction("Activation");
            historiqueCartes.setDetails("Activation du code Pin");
            historiqueCartes.setIp(carteClientQrDTO.getIp());
            historiqueCartes.setIdclients(loginClient.getClient().getId());
            historiqueCartes.setDateAction(LocalDateTime.now());
            historiqueCartes.setNumCarte(existingCardClientQr.getNumCarte());
            historiqueCartesRepository.save(historiqueCartes);

            /*SMSapi sms= new SMSapi();
            sms.alaSMS(loginClient.getClient().getPays().getIndicatif()  + loginClient.getLogin(),
                    "Votre carte HPay "+existingCardClientQr.getNumCarte()+" a été activé avec succès"
            );*/
        }

        //creation d'un objet HistoriqueCartes
        HistoriqueCartes historiqueCartes = new HistoriqueCartes();
        historiqueCartes.setAction("Changement PIN");
        historiqueCartes.setDetails("Changement du code pin lié à la carte");
        historiqueCartes.setIp(carteClientQrDTO.getIp());
        historiqueCartes.setIdclients(loginClient.getClient().getId());
        historiqueCartes.setDateAction(LocalDateTime.now());
        historiqueCartes.setNumCarte(existingCardClientQr.getNumCarte());
        historiqueCartesRepository.save(historiqueCartes);


        HashMap<String, Object> map = new HashMap<>();
        map.put("data",existingCardClientQr);
        return new SuccessResponse("Carte Activé/désactivé", 200, map );

    }


}
