/*
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
 * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
 */
package com.arrebol.taxiservicios.beans.registrarse;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.simpleemail.AmazonSimpleEmailService;
import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClientBuilder;
import com.amazonaws.services.simpleemail.model.Body;
import com.amazonaws.services.simpleemail.model.Content;
import com.amazonaws.services.simpleemail.model.Destination;
import com.amazonaws.services.simpleemail.model.Message;
import com.amazonaws.services.simpleemail.model.SendEmailRequest;
import com.amazonaws.services.simpleemail.model.SendEmailResult;
import com.arrebol.car.driver.security.CarDriverSecurity;
import com.arrebol.taxiservicios.beans.TaxiGenericBean;
import com.arrebol.taxiservicios.controller.admin.CustomerController;
import com.arrebol.taxiservicios.controller.admin.GenericPersonController;
import com.arrebol.taxiservicios.controller.admin.StableGeneralBoxController;
import com.arrebol.taxiservicios.controller.admin.StableSmallBoxController;
import com.arrebol.taxiservicios.controller.catalog.LocationController;
import com.arrebol.taxiservicios.controller.catalog.PaquetesController;
import com.arrebol.taxiservicios.controller.catalog.UserLocationController;
import com.arrebol.taxiservicios.controller.catalog.UserOpenPayController;
import com.arrebol.taxiservicios.controller.system.UserController;
import com.arrebol.taxiservicios.controller.system.UserHasPermissionController;
import com.arrebol.taxiservicios.model.admin.ClosingDay;
import com.arrebol.taxiservicios.model.admin.StableGeneralBox;
import com.arrebol.taxiservicios.model.admin.StableSmallBox;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.catalog.LocationPaquetes;
import com.arrebol.taxiservicios.model.catalog.Paquetes;
import com.arrebol.taxiservicios.model.catalog.UserLocation;
import com.arrebol.taxiservicios.model.catalog.UserOpenPay;
import com.arrebol.taxiservicios.model.core.Person;
import com.arrebol.taxiservicios.model.core.User;
import com.arrebol.taxiservicios.model.enums.BasicType;
import com.arrebol.taxiservicios.model.enums.GenericEnumType;
import com.arrebol.taxiservicios.model.enums.PersonType;
import com.arrebol.taxiservicios.model.enums.UserStatusType;
import java.io.Serializable;
import java.math.BigDecimal;
import java.security.SecureRandom;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import mx.openpay.client.Address;
import mx.openpay.client.Card;
import mx.openpay.client.Charge;
import mx.openpay.client.Customer;
import mx.openpay.client.core.OpenpayAPI;
import mx.openpay.client.core.requests.transactions.CreateCardChargeParams;
import mx.openpay.client.exceptions.OpenpayServiceException;
import mx.openpay.client.exceptions.ServiceUnavailableException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.primefaces.event.FlowEvent;
import java.math.RoundingMode;

/**
 *
 * @author pc one
 */
@Named("registrarseBean")
@ViewScoped
public class RegistrarseBean extends TaxiGenericBean implements Serializable {

    private static final long serialVersionUID = -2400590341745672164L;
    final Logger logger = LogManager.getLogger(getClass().getName());

    private boolean skip;
    private CustomerController customerController;
    private LocationController locationController;
    private GenericPersonController personController;
    private UserController userController;
    private UserLocationController userLocationController;
    private UserHasPermissionController userHasPermissionController;
    private UserOpenPayController userOpenPayController;
    private StableGeneralBoxController generalBoxController;
    private StableSmallBoxController smallBoxController;
    
    private Boolean correoVerificado;
    private String claveEnviada;    
    private String claveIngresada;
    private Boolean comprandoPack;
    private Boolean estatusAbPrivacidad;
    private String numeroPaks;

    private String mail;
    private String firstName;
    private String secondName;
    private String lastName;
    private String middleName;
    private Date birthdate;

    private String avatar;
    private Boolean enviandoCorreo;
    private Boolean guardandoUsuario;
    private Boolean claveValidada;
    private Boolean packDemo;
    private PaquetesController paquetesController;
    private List<Paquetes> ListPaquetes;

    private String selectIdPaquete;
    private Paquetes selectPaquete;
    private String nombreSelectIdPaquete;
    private Boolean formCompleto;

    private String cardTitular;
    private String cardTarjeta;
    private Integer cardExpiracionMes;
    private Integer cardExpiracionAno;
    private String cardDigitos;
    private String deviceSessionId;
    private String sourceId;

    private String cardDireccionCalle;
    private String cardDireccionNumero;
    private String cardDireccionCiudad;
    private String cardDireccionCodigoPostal;
    private String cardDireccionEstado;
    private String cardNumeroTelefono;
    private String customerOpenPay;

    @PostConstruct
    public void init() {
        logger.info("init");
        try {
            setPaquetesController(new PaquetesController());
            setListPaquetes(getPaquetesController().fillAllPaquetes());
            setPackDemo(true);
            setNombreSelectIdPaquete("DEMO");
            setSelectIdPaquete("f6277e17-d1a1-405b-ac40-4475c6ea8034");
            setNumeroPaks("1");

            loadBundlePropertyFile();
            setCorreoVerificado(false);
            setEnviandoCorreo(false);
            setComprandoPack(false);
            setClaveValidada(false);
            setGuardandoUsuario(false);
            setClaveIngresada(null);
            setClaveEnviada(null);

            setMail(null);
            setFirstName(null);
            setSecondName(null);
            setLastName(null);
            setMiddleName(null);
            setBirthdate(null);

        } catch (Exception e) {
            logger.error("init", e);
        }
    }

    public void enviarCorreo() {
        logger.info("enviarCorreo");
        if (!getEnviandoCorreo()) {
            setEnviandoCorreo(true);
            setPersonController(new GenericPersonController() {
            });
            setUserController(new UserController());
            List<Person> mailsPerson = getPersonController().getAllPersonsByMail(getMail());
            Boolean availableUserName = getUserController().availableUserName(getMail());
            if (mailsPerson.isEmpty() && availableUserName) {
                logger.info("enviarCorreo");
                int CODE_LENGTH = 4; // Longitud del código de verificación
                SecureRandom secureRandom = new SecureRandom();
                byte[] randomBytes = new byte[CODE_LENGTH];
                secureRandom.nextBytes(randomBytes);
                // Codificar los bytes aleatorios en una cadena legible
                String verificationCode = Base64.getUrlEncoder().withoutPadding().encodeToString(randomBytes);
                setClaveEnviada(verificationCode);
                // Se envía el código de deificación 
                setCheckEmail(getMail(), verificationCode);

            } else {
                setEnviandoCorreo(false);
                showMessage(FacesMessage.SEVERITY_ERROR, "Correo no disponible", "El correo que ingreso ya está registrado en el sistema ");
            }
        }
    }

    public void validarCorreo() {
        if (!getClaveValidada()) {
            if (getClaveEnviada() == null) {
                showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Primero debe de enviar el correo de verificación para validar la clave");
            } else if (getClaveEnviada().equals(getClaveIngresada())) {
                setCorreoVerificado(true);
                showMessage(FacesMessage.SEVERITY_INFO, "Correo verificado", "El correo fue verificado correctamente");
                logger.info("Correo verificado correctamente");
            } else {
                showMessage(FacesMessage.SEVERITY_ERROR, "Error al verificar el correo", "Clave de verificación incorrecta");
                logger.error("Clave de verificación incorrecta");
            }
        }
    }

    public void comprarPaquete() {
        logger.info("comprarPaquete");
        String privateKey = "sk_6310ee6c56c842a892b238eb3fc31eda";
        String merchantId = "m1al82yn7h3mdonrkdfe";
        OpenpayAPI api = new OpenpayAPI("https://sandbox-api.openpay.mx", privateKey, merchantId);
        Customer customer = new Customer();
        try {
            if(getComprandoPack()==false){
                setComprandoPack(true);
                logger.info("Empezando con la compra el paquete");                
                // se valida el numero paquetes que se compraran
                 Integer numeroDePaquetes = 1;
                switch (getNumeroPaks()) {
                     case "1":
                         numeroDePaquetes = 1;
                         break;
                     case "3":
                         numeroDePaquetes=3;
                         break;
                     case "6":
                         numeroDePaquetes=6;
                         break;
                      case "12":
                          numeroDePaquetes=12;
                         break;
                     default:
                         numeroDePaquetes=1;
                 }           
                 logger.info("Creando address OpenPay");
                 Address address = new Address();
                 address.city(getCardDireccionCiudad());
                 address.countryCode("MX");
                 address.state(getCardDireccionEstado());
                 address.postalCode(getCardDireccionCodigoPostal());
                 address.line1(getCardDireccionCalle());
                 //address.line2("Desarrollo San Pablo"); // =opcional
                 //address.line3("Qro. Qro."); // =opcional
                 logger.info("Creando customer OpenPay");                 
                 //customer.externalId(UUID.randomUUID().toString()); // =opcional DEBE DE SER UNICO
                 String nombres;
                 if(getSecondName() != null || !getSecondName().isEmpty()){
                      nombres = getFirstName() + " " + getSecondName();
                 }else{
                     nombres = getFirstName();
                 }            
                 String apellidos = getLastName() + " " + getMiddleName();
                 customer.name(nombres);
                 customer.lastName(apellidos);
                 customer.email(getMail());
                 customer.phoneNumber(getCardDireccionNumero());
                 customer.requiresAccount(false);
                 customer.address(address);
                 customer = api.customers().create(customer);                 
                 logger.info("Creando card OpenPay");
                 Card card = new Card();
                 card.holderName(getCardTitular());
                 card.cardNumber(getCardTarjeta());
                 card.cvv2(getCardDigitos());
                 card.expirationMonth(getCardExpiracionMes());
                 card.expirationYear(getCardExpiracionAno());
                 card.setDeviceSessionId(getDeviceSessionId());
                 card.address(address);
                 card = api.cards().create(customer.getId(), card);
                 logger.info("Realizando cargo al cliente OpenPay");
                 CreateCardChargeParams request = new CreateCardChargeParams();
                 String orderId = UUID.randomUUID().toString();
                 request.orderId(orderId); // =opcional DEBE DE SER UNICO
                 request.cardId(card.getId()); // =source_id            
                 
                 Double costo = getSelectPaquete().getCosto() * numeroDePaquetes.doubleValue();
                 BigDecimal monto = new BigDecimal(costo).setScale(2, RoundingMode.HALF_UP);                 
                 request.amount(monto);
                 
                 request.currency("MXN");
                 request.description("Compra de paquete " + getSelectPaquete().getNombre());
                 request.deviceSessionId(getDeviceSessionId());
                 Charge charge = api.charges().create(customer.getId(), request);
                 logger.info("Pago realizado correctamente");
                 // se crea el nuevo usuario
                 addCustomer(customer, card, numeroDePaquetes, orderId);
            }else{
                logger.error("Compra del paquete en proceso");
            }     
        } catch (OpenpayServiceException | ServiceUnavailableException e) {
            // Se elimina el cliente que se acababa de crear por error en la transacción
            try {
                api.customers().delete(customer.getId());
                logger.error("customer eliminado por error en la transacción");
            } catch (OpenpayServiceException | ServiceUnavailableException e2) {
                logger.error("Error al eliminar customer por error en la transacción"+e2);
            }            
            setComprandoPack(false);
            String errorDescription = null;
            String errorCode = null;
            if (e instanceof OpenpayServiceException) {
                OpenpayServiceException openpayException = (OpenpayServiceException) e;
                errorDescription = openpayException.getDescription();
                errorCode = openpayException.getErrorCode().toString();
            }      
            showMessage(FacesMessage.SEVERITY_ERROR, "Error " + errorCode, errorDescription);
            logger.error("Error openpay: " + e);
        }

    }

    public void addCustomer(Customer customerOpenPay, Card cardOpenPay, int packs, String orderId) {
        logger.info("addCustomer");
        try {
            if ((getFirstName() == null || "".equals(getFirstName())) || (getLastName() == null || "".equals(getLastName())) || (getMiddleName() == null || "".equals(getMiddleName())) || (getBirthdate() == null)) {
                logger.error("Formulario incompleto");
                showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Complete el formulario para registrase");
            } else if (!getGuardandoUsuario()) {
                logger.info("Creando usuario");
                setGuardandoUsuario(true);
                setCustomerController(new CustomerController());
                setLocationController(new LocationController());
                setPersonController(new GenericPersonController() {
                });
                setUserController(new UserController());
                setUserLocationController(new UserLocationController());
                setUserOpenPayController(new UserOpenPayController());                
                setGeneralBoxController(new StableGeneralBoxController());
                setSmallBoxController(new StableSmallBoxController());
                // Nueva locación de prueba
                logger.info("Creado locación");
                Location locationObj = new Location();                
                locationObj.setMaxPerson(1);
                if(getSelectPaquete().getNombre().equals("DEMO")){
                    locationObj.setDemo(true);
                    locationObj.setName("Locación DEMO");
                }else{
                    locationObj.setDemo(false);
                    locationObj.setName("Locación");
                }                
                // Se define la fecha en la que finalizara la demo a 30 días a partir de hoy
                Calendar fechaMas30 = Calendar.getInstance();
                fechaMas30.setTime(new Date());                
                 if(getSelectPaquete().getNombre().equals("DEMO")){
                    fechaMas30.add(Calendar.DAY_OF_MONTH, (getSelectPaquete().getVigencia()));
                }else{
                    fechaMas30.add(Calendar.DAY_OF_MONTH, (getSelectPaquete().getVigencia()*packs));
                }   
                locationObj.setFinDemo(fechaMas30.getTime());
                getLocationController().addLocation(locationObj, "09ea84b8-b9d1-4a71-adfe-db653b2a9982");

                //Se asigna el paquete 
                logger.info("Asignado paquete a la locación");
                setPaquetesController(new PaquetesController());
                // Se crea un nuevo registro para vincular paquetes con lotes
                LocationPaquetes newLocationPaquetes = new LocationPaquetes();
                newLocationPaquetes.setPaquete(getSelectPaquete());
                newLocationPaquetes.setLocation(locationObj);
                newLocationPaquetes.setFechaInicio(new Date());
                newLocationPaquetes.setLicencia(UUID.randomUUID().toString());
                newLocationPaquetes.setOpenPayOrderId(orderId);
                // se calcula la fecha en la que terminara el paquete
                Date fechaFin;
                if(getSelectPaquete().getNombre().equals("DEMO")){
                   fechaFin = fechaMasDias(new Date(), (getSelectPaquete().getVigencia()));
                   newLocationPaquetes.setCostoPaquete(getSelectPaquete().getCosto());
                }else{
                    fechaFin = fechaMasDias(new Date(), (getSelectPaquete().getVigencia()*packs));
                    newLocationPaquetes.setCostoPaquete(getSelectPaquete().getCosto()*packs);
                }   
                newLocationPaquetes.setFechaFin(fechaFin);
                newLocationPaquetes.setNombrePaquete(getSelectPaquete().getNombre());                
                newLocationPaquetes.setEstatusActivo(GenericEnumType.ENABLED);
                getPaquetesController().addLocationPaquetes(newLocationPaquetes, new User("09ea84b8-b9d1-4a71-adfe-db653b2a9982", ""), true);

                // nueva persona
                logger.info("Creado persona");
                Person customer = new Person();
                customer.setId(UUID.randomUUID().toString());
                // datos formulario
                customer.setFirstName(getFirstName());
                customer.setSecondName(getSecondName());
                customer.setLastName(getLastName());
                customer.setMiddleName(getMiddleName());
                customer.setBirthdate(getBirthdate());
                //
                customer.setPersonType(PersonType.EMPLOYEE);
                customer.setActive(true);
                customer.setRoot(false);
                customer.setCreatedOn(new Date());
                customer.setLocation(locationObj);
                customer.setMail(getMail());
                customer.setPassword(new CarDriverSecurity(APP, "12345678").getPassword());
                getCustomerController().addPerson(customer, "ruben.campos", true);

                // se crea un nuevo usuario 
                logger.info("Creado nuevo usuario");
                User user = new User(UUID.randomUUID().toString(),true,customer.getMail(), customer.getPassword(), Boolean.TRUE, "09ea84b8-b9d1-4a71-adfe-db653b2a9982");
                user.setUserStatusType(UserStatusType.ENABLED);
                user.setCreatedOn(new Date());
                getUserController().createUserByLocationAllPermission(user, customer.getId(), "images/avatar/mask-power/mask-1.png", locationObj.getId());
                               
                // Fecha menos un mes para el nuevo corte           
                Calendar calendar = Calendar.getInstance();
                calendar.add(Calendar.MONTH, -1);   
                 // Se crea un corte en 0
                logger.info("Creando nuevo ClosingDay en 0");
                ClosingDay closingDay = new ClosingDay();
                closingDay.setId(UUID.randomUUID().toString());
                closingDay.setUser(user);
                closingDay.setAmountPaid(new BigDecimal(0));
                closingDay.setAmountExpected(new BigDecimal(0));
                closingDay.setAmountTransfer(new BigDecimal(0));
                closingDay.setActiveStatus(BasicType.ENEBLED);
                closingDay.setComments("Corte 0 agregado por creación de nuevo usuario");
                closingDay.setCreatedBy(new User("09ea84b8-b9d1-4a71-adfe-db653b2a9982", ""));                             
                closingDay.setCreatedOn(calendar.getTime());
                closingDay.setLocation(locationObj);
                getUserController().addClosingDateToNewUser(closingDay);
                
                 // Se crea un corte en 0
                logger.info("Creando nuevo StableGeneralBox en 0");
                StableGeneralBox generalBox = new StableGeneralBox();
                generalBox.setId(UUID.randomUUID().toString());
                generalBox.setTotalGeneralBox(new BigDecimal(0));
                generalBox.setTotalEnvelope(new BigDecimal(0));
                generalBox.setTotalBankNote(new BigDecimal(0));
                generalBox.setTotalCoin(new BigDecimal(0));
                generalBox.setTotalStable(new BigDecimal(0));
                generalBox.setTotalBank(new BigDecimal(0));
                generalBox.setActiveStatus(BasicType.ENEBLED);
                generalBox.setDescription("Corte 0 agregado por creación de nuevo usuario");
                generalBox.setCreatedBy(new User("09ea84b8-b9d1-4a71-adfe-db653b2a9982", ""));
                generalBox.setCreatedOn(calendar.getTime());    
                generalBox.setLocation(locationObj);
                getGeneralBoxController().saveStableGeneralBox(generalBox);
                
                // Se crea un corte en 0
                logger.info("Creando nuevo StableSmallBox en 0");
                StableSmallBox smallBox = new StableSmallBox();
                smallBox.setId(UUID.randomUUID().toString());
                smallBox.setTotalSmallBox(new BigDecimal(0));
                smallBox.setTotalEnvelope(new BigDecimal(0));
                smallBox.setTotalBankNote(new BigDecimal(0));
                smallBox.setTotalCoin(new BigDecimal(0));
                smallBox.setTotalStable(new BigDecimal(0));
                smallBox.setTotalTransfer(new BigDecimal(0));
                smallBox.setActiveStatus(BasicType.ENEBLED);
                smallBox.setDescription("Corte 0 agregado por creación de nuevo usuario");
                smallBox.setCreatedBy(new User("09ea84b8-b9d1-4a71-adfe-db653b2a9982", ""));
                smallBox.setCreatedOn(calendar.getTime());
                smallBox.setLocation(locationObj);
                getSmallBoxController().saveStableSmallBox(smallBox);

                // se crea un nuevo registro en UserLocation  
                logger.info("Creado un nuevo registro en UserLocation");
                UserLocation usLo = new UserLocation();
                usLo.setLocation(locationObj);
                usLo.setUser(user);
                usLo.setPagoAutomatico(0);
                usLo.setEstatusActivo(GenericEnumType.ENABLED);
                getUserLocationController().addUserLocation(usLo, user, true);
                
                 // se crea un nuevo registro en UserOpenPay  
                 if (customerOpenPay!=null) {
                     logger.info("Creado un nuevo registro en UserOpenPay");
                    UserOpenPay usOpenPay = new UserOpenPay();
                    usOpenPay.setUser(user);
                    usOpenPay.setIdClienteOpenPay(customerOpenPay.getId());
                    usOpenPay.setIdTargetaOpenPay(cardOpenPay.getId());
                    usOpenPay.setEstatusActivo(GenericEnumType.ENABLED);
                    getUserOpenPayController().addUserOpenPay(usOpenPay, new User("09ea84b8-b9d1-4a71-adfe-db653b2a9982", ""), true);
                }                
                
                if(getSelectPaquete().getNombre().equals("DEMO")){
                   setBienvenidaEmail(customer.getMail(), "12345678");
                   setDemoEmail(customer.getMail());
                }else{
                    setBienvenidaEmail(customer.getMail(), "12345678");
                }   
                showMessage(FacesMessage.SEVERITY_INFO, "Usuario creado correctamente", "Ahora puede ingresar a la plataforma con su usuario(correo) y contraseña");
                logger.info("Usuario creado correctamente");
                init();
            } else {
                logger.info("Guardando usuario");
            }
        } catch (Exception e) {
            setGuardandoUsuario(false);
            showMessage(FacesMessage.SEVERITY_ERROR, "Error a al crear el usuario", "Ocurrió un error al crear el usuario");
            logger.error("Error al registrarse en el sistema ");
        }
    }

    private boolean setCheckEmail(String mail, String clave) {
        logger.info("setCheckEmail");
        String ACCESS_KEY = getBundlePropertyFile().getString("aws.access.key");
        String SECRET_KEY = getBundlePropertyFile().getString("aws.secret.access.key");

        // Remitente y destinatario
        String sender = "soporte@crovonline.com";
        String recipient = mail;

        // Configurar credenciales de AWS
        BasicAWSCredentials awsCredentials = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY);
        AmazonSimpleEmailService client = AmazonSimpleEmailServiceClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                .withRegion(getBundlePropertyFile().getString("aws.region")) // Cambia la región según tus necesidades
                .build();

        String SUBJECT = "Código de Validación para CROV Inmobiliaria";

        String HTMLBODY = "<h1>Verificación de Correo Electrónico CROV Inmobiliaria</h1>"
                + "<p>Código de Verificación: " + clave + "</p>";

        String TEXTBODY = "Este mensaje ha sido enviado automáticamente desde CROV Inmobiliaria.\n\n";

        // Crear el mensaje
        SendEmailRequest request = new SendEmailRequest()
                .withDestination(new Destination().withToAddresses(recipient))
                .withMessage(new Message()
                        .withBody(new Body()
                                .withHtml(new Content()
                                        .withCharset("UTF-8").withData(HTMLBODY))
                                .withText(new Content()
                                        .withCharset("UTF-8").withData(TEXTBODY)))
                        .withSubject(new Content()
                                .withCharset("UTF-8").withData(SUBJECT)))
                .withSource(sender);

        // Enviar el correo
        try {
            SendEmailResult result = client.sendEmail(request);
            showMessage(FacesMessage.SEVERITY_INFO, "El correo se ha enviado correctamente", "El correo se ha enviado correctamente");
            logger.info("El correo se ha enviado correctamente. ID del mensaje: " + result.getMessageId());
            return true;
        } catch (AmazonServiceException ex) {
            showMessage(FacesMessage.SEVERITY_ERROR, "Error al enviar el correo", "Error al enviar el correo");
            logger.error("Error al enviar el correo: " + ex.getMessage());
            return false;
        }
    }

    private boolean setBienvenidaEmail(String mail, String password) {
        logger.info("setBienvenidaEmail");
        String ACCESS_KEY = getBundlePropertyFile().getString("aws.access.key");
        String SECRET_KEY = getBundlePropertyFile().getString("aws.secret.access.key");

        // Remitente y destinatario
        String sender = "soporte@crovonline.com";
        String recipient = mail;

        // Configurar credenciales de AWS
        BasicAWSCredentials awsCredentials = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY);
        AmazonSimpleEmailService client = AmazonSimpleEmailServiceClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                .withRegion(getBundlePropertyFile().getString("aws.region")) // Cambia la región según tus necesidades
                .build();

                 String SUBJECT = "¡Bienvenido a CROV Inmobiliaria!";

                String HTMLBODY = "<h1>Bienvenido a CROV Inmobiliaria</h1>" 
                        + "<p>«Esta es una notificación automática - Favor de NO responder (reply) a este email»</p>" 
                        + "<p>Estimado Usuario,</p>" 
                        + "<p>Te damos la bienvenida a CROV Inmobiliaria. Tu registro en nuestro sistema ha sido exitoso.</p>" 
                        + "<p>A continuación, te proporcionamos tus datos de inicio de sesión:</p>" 
                        + "<p><strong>Usuario:</strong> " + mail + "</p>" 
                        + "<p><strong>Contraseña:</strong> " + password + "</p>"                         
                        + "<p>¡Gracias por unirte a nosotros!</p>"                                              
                        + "<p>Le recomendamos darle una mirada a los videos instruccionales sobre cómo usar las diferentes partes de nuestro sistema. Son pequeños videos muy fáciles de entender. <a href=‘crovonline.com’>Haga click aquí para verlos.</a></p>" 
                        + "<p>Si tiene alguna duda o comentario, por favor envíenos un email a soporte@crovinmobiliaria.com</p>" 
                        + "<p>Ya puedes descargar nuestra aplicación oficial <a href=‘play.google.com’>App oficial</a> desde la Play Store.</p>" 
                        + "<p>CROV Inmobiliaria</p>";

                String TEXTBODY = "Este mensaje ha sido enviado automáticamente desde CROV Inmobiliaria.\n\n";

        // Crear el mensaje
        SendEmailRequest request = new SendEmailRequest()
                .withDestination(new Destination().withToAddresses(recipient))
                .withMessage(new Message()
                        .withBody(new Body()
                                .withHtml(new Content()
                                        .withCharset("UTF-8").withData(HTMLBODY))
                                .withText(new Content()
                                        .withCharset("UTF-8").withData(TEXTBODY)))
                        .withSubject(new Content()
                                .withCharset("UTF-8").withData(SUBJECT)))
                .withSource(sender);

        // Enviar el correo
        try {
            SendEmailResult result = client.sendEmail(request);
            logger.info("El correo se ha enviado correctamente. ID del mensaje: " + result.getMessageId());
            return true;
        } catch (AmazonServiceException ex) {
            logger.error("Error al enviar el correo: " + ex.getMessage());
            return false;
        }
    }
    
    private boolean setDemoEmail(String mail) {
        logger.info("setDemoEmail");
        String ACCESS_KEY = getBundlePropertyFile().getString("aws.access.key");
        String SECRET_KEY = getBundlePropertyFile().getString("aws.secret.access.key");

        // Remitente y destinatario
        String sender = "soporte@crovonline.com";
        String recipient = mail;

        // Configurar credenciales de AWS
        BasicAWSCredentials awsCredentials = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY);
        AmazonSimpleEmailService client = AmazonSimpleEmailServiceClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                .withRegion(getBundlePropertyFile().getString("aws.region")) // Cambia la región según tus necesidades
                .build();

                 String SUBJECT = "¡Bienvenido a CROV Inmobiliaria! Comienza tu mes de prueba.";

                 String HTMLBODY = "<p>¡Gracias por dar inicio a tu período de prueba en CROV Inmobiliaria!</p>"
                        + "<p>Esperamos que aproveches al máximo este período de prueba. Estamos aquí para brindarte todo el apoyo, capacitación y asesoría que necesites, así como para ayudarte con la carga inicial de información en nuestra plataforma.</p>"
                        + "<p>Para comenzar con la carga de información, adjuntamos nuestra plantilla de Excel. Una vez que la hayas completado, por favor envíala a <a href='mailto:soporte@crovonline.com'>soporte@crovonline.com</a>.</p>"
                        + "<p>Recuerda que ofrecemos webinars y sesiones virtuales donde te guiarán desde la configuración de tu cuenta hasta el manejo avanzado de la plataforma. ¡Y lo mejor de todo es que son completamente gratuitos!</p>"
                        + "<p>Puedes consultar nuestro calendario de capacitaciones haciendo <a href='enlace_calendario'>clic aquí</a>.</p>"
                        + "<p>Si necesitas ayuda adicional, no dudes en ponerte en contacto con nosotros a través de este medio o utilizando los datos de contacto que encontrarás al final del mensaje.</p>"
                        + "<p>CONFIGURA TU CUENTA Y DESCUBRE NUESTROS TUTORIALES:</p>"
                        + "<p><a href='https://crovonline.com'>https://crovonline.com</a></p>"
                        + "<p>En nuestro próximo correo, te proporcionaremos más material de apoyo.</p>"
                        + "<p>Atentamente,</p>";

                String TEXTBODY = "Este mensaje ha sido enviado automáticamente desde CROV Inmobiliaria.\n\n";



        // Crear el mensaje
        SendEmailRequest request = new SendEmailRequest()
                .withDestination(new Destination().withToAddresses(recipient))
                .withMessage(new Message()
                        .withBody(new Body()
                                .withHtml(new Content()
                                        .withCharset("UTF-8").withData(HTMLBODY))
                                .withText(new Content()
                                        .withCharset("UTF-8").withData(TEXTBODY)))
                        .withSubject(new Content()
                                .withCharset("UTF-8").withData(SUBJECT)))
                .withSource(sender);

        // Enviar el correo
        try {
            SendEmailResult result = client.sendEmail(request);
            logger.info("El correo se ha enviado correctamente. ID del mensaje: " + result.getMessageId());
            return true;
        } catch (AmazonServiceException ex) {
            logger.error("Error al enviar el correo: " + ex.getMessage());
            return false;
        }
    }

    public void selectDemo() {
        if (getPackDemo()) {
            setNombreSelectIdPaquete("DEMO");
            setSelectIdPaquete("f6277e17-d1a1-405b-ac40-4475c6ea8034");
        }
    }

    public void resetPack() {
        setPackDemo(true);
        setNombreSelectIdPaquete("DEMO");
        setSelectIdPaquete("f6277e17-d1a1-405b-ac40-4475c6ea8034");
    }

    public void valForm() {
        if (getFirstName() != null && !"".equals(getFirstName()) && getLastName() != null && !"".equals(getLastName()) && getMiddleName() != null && !"".equals(getMiddleName()) && getBirthdate() != null) {
            setFormCompleto(true);
        } else {
            setFormCompleto(false);
        }
    }

    private Date fechaMasDias(Date fecha, Integer dias) {
        // Convertir la fecha proporcionada a un objeto ZonedDateTime
        ZonedDateTime zonedDateTime = fecha.toInstant().atZone(ZoneId.systemDefault());
        // Sumar los días al objeto ZonedDateTime
        ZonedDateTime nuevaFecha = zonedDateTime.plusDays(dias);
        // Convertir el resultado nuevamente a un objeto Date
        return Date.from(nuevaFecha.toInstant());
    }

    public void cargarPaquete(String pack) {
        try {
            Paquetes pa = getPaquetesController().findPaqueteById(pack);
            setSelectPaquete(pa);
            setSelectIdPaquete(pa.getId());
            setNombreSelectIdPaquete(pa.getNombre());
        } catch (Exception e) {
            showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Error al seleccionar el paquete");
        }
    }

    public boolean isSkip() {
        return skip;
    }

    public void setSkip(boolean skip) {
        this.skip = skip;
    }

    public String onFlowProcess(FlowEvent event) {
        if (skip) {
            skip = false; //reset in case user goes back
            valForm();
            return "confirm";
        } else {
            valForm();
            return event.getNewStep();
        }
    }

    public CustomerController getCustomerController() {
        return customerController;
    }

    public void setCustomerController(CustomerController customerController) {
        this.customerController = customerController;
    }

    public LocationController getLocationController() {
        return locationController;
    }

    public void setLocationController(LocationController locationController) {
        this.locationController = locationController;
    }

    public Boolean getCorreoVerificado() {
        return correoVerificado;
    }

    public void setCorreoVerificado(Boolean correoVerificado) {
        this.correoVerificado = correoVerificado;
    }

    public String getMail() {
        return mail;
    }

    public void setMail(String mail) {
        this.mail = mail;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getSecondName() {
        return secondName;
    }

    public void setSecondName(String secondName) {
        this.secondName = secondName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getMiddleName() {
        return middleName;
    }

    public void setMiddleName(String middleName) {
        this.middleName = middleName;
    }

    public Date getBirthdate() {
        return birthdate;
    }

    public void setBirthdate(Date birthdate) {
        this.birthdate = birthdate;
    }

    public String getClaveEnviada() {
        return claveEnviada;
    }

    public void setClaveEnviada(String claveEnviada) {
        this.claveEnviada = claveEnviada;
    }

    public String getClaveIngresada() {
        return claveIngresada;
    }

    public void setClaveIngresada(String claveIngresada) {
        this.claveIngresada = claveIngresada;
    }

    public GenericPersonController getPersonController() {
        return personController;
    }

    public void setPersonController(GenericPersonController personController) {
        this.personController = personController;
    }

    public UserController getUserController() {
        return userController;
    }

    public void setUserController(UserController userController) {
        this.userController = userController;
    }

    public UserLocationController getUserLocationController() {
        return userLocationController;
    }

    public void setUserLocationController(UserLocationController userLocationController) {
        this.userLocationController = userLocationController;
    }

    public String getAvatar() {
        if (null == avatar) {
            avatar = "images/unknown_user.png";
        }
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    public Boolean getEnviandoCorreo() {
        return enviandoCorreo;
    }

    public void setEnviandoCorreo(Boolean enviandoCorreo) {
        this.enviandoCorreo = enviandoCorreo;
    }

    public Boolean getGuardandoUsuario() {
        return guardandoUsuario;
    }

    public void setGuardandoUsuario(Boolean guardandoUsuario) {
        this.guardandoUsuario = guardandoUsuario;
    }

    public UserHasPermissionController getUserHasPermissionController() {
        return userHasPermissionController;
    }

    public void setUserHasPermissionController(UserHasPermissionController userHasPermissionController) {
        this.userHasPermissionController = userHasPermissionController;
    }

    public Boolean getClaveValidada() {
        return claveValidada;
    }

    public void setClaveValidada(Boolean claveValidada) {
        this.claveValidada = claveValidada;
    }

    public Boolean getPackDemo() {
        return packDemo;
    }

    public void setPackDemo(Boolean packDemo) {
        this.packDemo = packDemo;
    }

    public PaquetesController getPaquetesController() {
        return paquetesController;
    }

    public void setPaquetesController(PaquetesController paquetesController) {
        this.paquetesController = paquetesController;
    }

    public List<Paquetes> getListPaquetes() {
        return ListPaquetes;
    }

    public void setListPaquetes(List<Paquetes> ListPaquetes) {
        this.ListPaquetes = ListPaquetes;
    }

    public String getSelectIdPaquete() {
        return selectIdPaquete;
    }

    public void setSelectIdPaquete(String selectIdPaquete) {
        this.selectIdPaquete = selectIdPaquete;
    }

    public String getNombreSelectIdPaquete() {
        return nombreSelectIdPaquete;
    }

    public void setNombreSelectIdPaquete(String nombreSelectIdPaquete) {
        this.nombreSelectIdPaquete = nombreSelectIdPaquete;
    }

    public Boolean getFormCompleto() {
        return formCompleto;
    }

    public void setFormCompleto(Boolean formCompleto) {
        this.formCompleto = formCompleto;
    }

    public String getCardTitular() {
        return cardTitular;
    }

    public void setCardTitular(String cardTitular) {
        this.cardTitular = cardTitular;
    }

    public String getCardTarjeta() {
        return cardTarjeta;
    }

    public void setCardTarjeta(String cardTarjeta) {
        this.cardTarjeta = cardTarjeta;
    }

    public Integer getCardExpiracionMes() {
        return cardExpiracionMes;
    }

    public void setCardExpiracionMes(Integer cardExpiracionMes) {
        this.cardExpiracionMes = cardExpiracionMes;
    }

    public Integer getCardExpiracionAno() {
        return cardExpiracionAno;
    }

    public void setCardExpiracionAno(Integer cardExpiracionAno) {
        this.cardExpiracionAno = cardExpiracionAno;
    }

    public String getCardDigitos() {
        return cardDigitos;
    }

    public void setCardDigitos(String cardDigitos) {
        this.cardDigitos = cardDigitos;
    }

    public String getDeviceSessionId() {
        return deviceSessionId;
    }

    public void setDeviceSessionId(String deviceSessionId) {
        this.deviceSessionId = deviceSessionId;
    }

    public String getCardDireccionCalle() {
        return cardDireccionCalle;
    }

    public void setCardDireccionCalle(String cardDireccionCalle) {
        this.cardDireccionCalle = cardDireccionCalle;
    }

    public String getCardDireccionNumero() {
        return cardDireccionNumero;
    }

    public void setCardDireccionNumero(String cardDireccionNumero) {
        this.cardDireccionNumero = cardDireccionNumero;
    }

    public String getCardDireccionCiudad() {
        return cardDireccionCiudad;
    }

    public void setCardDireccionCiudad(String cardDireccionCiudad) {
        this.cardDireccionCiudad = cardDireccionCiudad;
    }

    public String getCardDireccionCodigoPostal() {
        return cardDireccionCodigoPostal;
    }

    public void setCardDireccionCodigoPostal(String cardDireccionCodigoPostal) {
        this.cardDireccionCodigoPostal = cardDireccionCodigoPostal;
    }

    public String getCardDireccionEstado() {
        return cardDireccionEstado;
    }

    public void setCardDireccionEstado(String cardDireccionEstado) {
        this.cardDireccionEstado = cardDireccionEstado;
    }

    public String getCardNumeroTelefono() {
        return cardNumeroTelefono;
    }

    public void setCardNumeroTelefono(String cardNumeroTelefono) {
        this.cardNumeroTelefono = cardNumeroTelefono;
    }

    public String getSourceId() {
        return sourceId;
    }

    public void setSourceId(String sourceId) {
        this.sourceId = sourceId;
    }

    public Paquetes getSelectPaquete() {
        return selectPaquete;
    }

    public void setSelectPaquete(Paquetes selectPaquete) {
        this.selectPaquete = selectPaquete;
    }

    public Boolean getEstatusAbPrivacidad() {
        return estatusAbPrivacidad;
    }

    public void setEstatusAbPrivacidad(Boolean estatusAbPrivacidad) {
        this.estatusAbPrivacidad = estatusAbPrivacidad;
    }

    public String getNumeroPaks() {
        return numeroPaks;
    }

    public void setNumeroPaks(String numeroPaks) {
        this.numeroPaks = numeroPaks;
    }

    public UserOpenPayController getUserOpenPayController() {
        return userOpenPayController;
    }

    public void setUserOpenPayController(UserOpenPayController userOpenPayController) {
        this.userOpenPayController = userOpenPayController;
    }

    public Boolean getComprandoPack() {
        return comprandoPack;
    }

    public void setComprandoPack(Boolean comprandoPack) {
        this.comprandoPack = comprandoPack;
    }

    public String getCustomerOpenPay() {
        return customerOpenPay;
    }

    public void setCustomerOpenPay(String customerOpenPay) {
        this.customerOpenPay = customerOpenPay;
    }

    public StableGeneralBoxController getGeneralBoxController() {
        return generalBoxController;
    }

    public void setGeneralBoxController(StableGeneralBoxController generalBoxController) {
        this.generalBoxController = generalBoxController;
    }

    public StableSmallBoxController getSmallBoxController() {
        return smallBoxController;
    }

    public void setSmallBoxController(StableSmallBoxController smallBoxController) {
        this.smallBoxController = smallBoxController;
    }

}
