/*
 * Arrebol Consultancy copyright.
 *
 * This code belongs to Arrebol Consultancy
 * its use, redistribution or modification are prohibited
 * without written authorization from Arrebol Consultancy.
 */
package com.arrebol.taxiservicios.beans.admin.client;

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.GenericPersonBean;
import com.arrebol.taxiservicios.controller.admin.CustomerController;
import com.arrebol.taxiservicios.controller.admin.DriverController;
import com.arrebol.taxiservicios.controller.admin.GenericPersonController;
import com.arrebol.taxiservicios.controller.system.UserController;
import com.arrebol.taxiservicios.model.core.Person;
import com.arrebol.taxiservicios.model.enums.PersonType;
import com.arrebol.taxiservicios.model.view.PersonListView;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.primefaces.context.RequestContext;

/**
 *
 * @author Carlos Janitzio Zavala Lopez <janitzio.zavala@arrebol.com.mx>
 */
@Named("customersListBean")
@ViewScoped
public class CustomersListBean extends GenericPersonBean implements Serializable {

   /**
    *
    * @param outcome
    * @return
    */
   public String editCustomer(String outcome) {
      return outcome;
   }

   public void deleteCustomerSelected() {
      try {
         if (null == getLoggedUser().getPerson()
                 || null == getLoggedUser().getPerson().getId()
                 || getLoggedUser().getPerson().getId().equals(getSelectedCustomer().getId())) {
            showMessage(FacesMessage.SEVERITY_WARN,
                    getBundlePropertyFile().getString("customer.delete.title"),
                    getBundlePropertyFile().getString(
                            null == getLoggedUser().getPerson()
                            || null == getLoggedUser().getPerson().getId()
                            ? "customer.delete.cannot.empty"
                            : "customer.delete.cannot.delete"
                    ));
         } else {
            boolean success = getController().deletePersonById(
                    getSelectedCustomer().getId(), getLoggedUser().getUserName());

            if (success) {
               getCustomers().remove(getSelectedCustomer());
               setSelectedCustomer(null);
               setCustomers(getController().findListOfPersonsByType(PersonType.CUSTOMER, getLoggedUser().getLocation()));

               showMessage(FacesMessage.SEVERITY_INFO,
                       getBundlePropertyFile().getString("customer.delete.title"),
                       getBundlePropertyFile().getString("customer.delete.success.desc"));
            } else {
               logger.error("Customer " + getSelectedCustomer() + "was not deleted");
               showMessage(FacesMessage.SEVERITY_ERROR,
                       getBundlePropertyFile().getString("customer.delete.title"),
                       getBundlePropertyFile().getString("customer.delete.fail.desc"));
            }
         }
      } catch (Exception e) {
         logger.error("deleteRow: " + e);

         showMessage(FacesMessage.SEVERITY_FATAL,
                 getBundlePropertyFile().getString("customer.delete.title"),
                 getBundlePropertyFile().getString("customer.delete.exception.desc"));
      }
   }

   public void checkAndCreateUser() {
      if (selectedCustomer != null && (selectedCustomer.getMail() == null || selectedCustomer.getMail().isEmpty())) {
         System.out.println("Correo electrónico nulo o vacío");
         RequestContext context = RequestContext.getCurrentInstance();
         context.execute("nullMailDlg.show();");
      } else {
         System.out.println("Creando usuario...");
         // Lógica para crear el usuario
         createUserCustomerSelected();
      }
   }

   public void createUserCustomerSelected() {

      try {
         if (null == getLoggedUser().getPerson()
                 || null == getLoggedUser().getPerson().getId()
                 || getLoggedUser().getPerson().getId().equals(getSelectedCustomer().getId())) {
            showMessage(FacesMessage.SEVERITY_WARN,
                    getBundlePropertyFile().getString("customer.delete.title"),
                    getBundlePropertyFile().getString(
                            null == getLoggedUser().getPerson()
                            || null == getLoggedUser().getPerson().getId()
                            ? "customer.delete.cannot.empty"
                            : "customer.delete.cannot.delete"
                    ));
         } else {

            if (getSelectedCustomer().getMail() == null || getSelectedCustomer().getMail().equals("''")) {
               showMessage(FacesMessage.SEVERITY_ERROR,
                       "Correo Necesario",
                       "No se puede inicializar el usario si el cliente no tiene un email asignado");
               return;
            }

            String password = new CarDriverSecurity(APP, "12345678").getPassword();
            boolean success = getController().CreateUserPersonById(
                    getSelectedCustomer().getId(), password, getLoggedUser());

            if (success) {
               setCustomers(getController().findListOfPersonsByType(PersonType.CUSTOMER, getLoggedUser().getLocation()));
               // Se envía correo electrónico con los datos de acceso
               setEmail(getSelectedCustomer().getMail(), "12345678");
               showMessage(FacesMessage.SEVERITY_INFO, "Credenciales iniciales", "La contraseña inicial del usuario fue creada con exito");
            } else {
               logger.error("Customer " + getSelectedCustomer() + " user was not created");
               showMessage(FacesMessage.SEVERITY_ERROR,
                       getBundlePropertyFile().getString("customer.delete.title"),
                       getBundlePropertyFile().getString("customer.delete.fail.desc"));
            }
         }
      } catch (Exception e) {
         logger.error("deleteRow: " + e);

         showMessage(FacesMessage.SEVERITY_FATAL,
                 getBundlePropertyFile().getString("customer.delete.title"),
                 getBundlePropertyFile().getString("customer.delete.exception.desc"));
      }
   }

   public void saveCustomer() {
      logger.info(getSelectedCustomer().getMail());
      // Validación del correo electrónico
      setUserController(new UserController());
      setPersonController(new GenericPersonController() {
      });
      List<Person> mailsPerson = getPersonController().getAllPersonsByMail(getSelectedCustomer().getMail());
      Boolean availableUserName = getUserController().availableUserName(getSelectedCustomer().getMail());
      if (mailsPerson.isEmpty() && availableUserName) {
         Person person = getCustomerController().getPersonById(getSelectedCustomer().getId());
         person.setMail(getSelectedCustomer().getMail());
         boolean success = getCustomerController().addPerson(person, getLoggedUser().getUserName(), false);
         if (success) {
            createUserCustomerSelected();
         } else {
            showMessage(FacesMessage.SEVERITY_ERROR, "Error", "No se pudo actualizar el usuario");
            logger.error("No se pudo actualizar el usuario");
         }
      } else {
         showMessage(FacesMessage.SEVERITY_ERROR, "Error", "El correo electrónico ya está registrado");
         logger.error("El correo electrónico ya está registrado");
         setCustomers(getController().findListOfPersonsByType(PersonType.CUSTOMER, getLoggedUser().getLocation()));
      }
   }

   private boolean setEmail(String mail, String password) {
      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>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>Correo:</strong> " + mail + "</p>"
              + "<p><strong>Contraseña:</strong> " + password + "</p>"
              + "<p>Ya puedes descargar nuestra aplicación oficial <a href='play.google.com'>App oficial</a> desde la Play Store.</p>"
              + "<p>¡Gracias por unirte a nosotros!</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 static final long serialVersionUID = -7284027390656669184L;

   final Logger logger = LogManager.getLogger(getClass());

   private List<PersonListView> customers;
   private PersonListView selectedCustomer;
   private CustomerController customerController;
   private UserController userController;
   private GenericPersonController personController;

   @PostConstruct
   public void init() {
      try {
         loadBundlePropertyFile();
         setCustomerController(new CustomerController());
         setController(new DriverController());

         setCustomers(getController().findListOfPersonsByType(PersonType.CUSTOMER, getLoggedUser().getLocation()));

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

   public boolean validarCorreo(String correo) {
      try {
         // valida si el correo es null
         if (correo == null) {

            return false;
         } else {
            // Patrón de expresión regular para validar un correo electrónico
            String patron = "^[A-Za-z0-9+_.-]+@(.+)$";

            // Compila el patrón en un objeto Pattern
            Pattern pattern = Pattern.compile(patron);

            // Crea un objeto Matcher para la cadena de texto
            Matcher matcher = pattern.matcher(correo);

            // Comprueba si el correo electrónico coincide con el patrón
            if (matcher.matches()) {
               return true;
            } else {

               return false;
            }
         }
      } catch (Exception e) {
         logger.error("validarCorreo: ", e);
         return false;
      }

   }

   public List<PersonListView> getCustomers() {
      if (null == customers) {
         customers = new ArrayList<>();
      }
      return customers;
   }

   public void setCustomers(List<PersonListView> customers) {
      this.customers = customers;
   }

   public PersonListView getSelectedCustomer() {
      return selectedCustomer;
   }

   public void setSelectedCustomer(PersonListView selectedCustomer) {
      this.selectedCustomer = selectedCustomer;

   }

   public CustomerController getCustomerController() {
      return customerController;
   }

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

   public UserController getUserController() {
      return userController;
   }

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

   public GenericPersonController getPersonController() {
      return personController;
   }

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