/*
 * 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.resetPassword;

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.system.UserController;
import com.arrebol.taxiservicios.controller.system.UserHasPermissionController;
import com.arrebol.taxiservicios.model.core.User;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.Date;
import java.util.Locale;
import javax.annotation.PostConstruct;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
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;

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

    private static final long serialVersionUID = -2400590341745672164L;
    final Logger logger = LogManager.getLogger(getClass());
    private UserController userController;
    private CustomerController customerController;
    private UserHasPermissionController userHasPermissionController;
    private String password;
    private String password2;
    private String username;
    private String usernameL;
    private String expiracionLink;
    private static final String KEY = "Xy3P9kAq7RtZvWbC";
    private static final String ALGOR = "AES";

    @PostConstruct
    public void init() {
        logger.info("init");
        try {
            loadBundlePropertyFile();
            try {
                String us = decrypt(externalContext().getRequestParameterMap().get("user"));
                String fe = decrypt(externalContext().getRequestParameterMap().get("date"));
                setUsernameL(us);
                setExpiracionLink(fe);
            } catch (Exception e) {
                setUsernameL(null);
                setExpiracionLink(null);
            }
        } catch (Exception e) {
            logger.error("init", e);
        }
    }

    public void enviarCorreo() {
        logger.info("enviarCorreo");
        try {
            setUserController(new UserController());
            User user = getUserController().getByUserName(getUsername());
            if (user != null) {
                String name = encrypt(getUsername());
                String expiration = encrypt(new Date().toString());
                String link = "http://inmobiliariaprod-env.eba-txvq9eis.us-east-2.elasticbeanstalk.com/actualizarPassword.jsf?user=" + name + "&date=" + expiration;
                if (resetPasswordEmail(user.getPerson().getMail(), link)) {
                    showMessage(FacesMessage.SEVERITY_INFO, "El correo se ha enviado", "Se envió un correo de recuperación a su correo electrónico");
                } else {
                    showMessage(FacesMessage.SEVERITY_ERROR, "Error al enviar el correo", "Ocurrió un erro al enviar el correo de recuperación");
                }
            } else {
                showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Usuario no encontrado");
            }
        } catch (Exception e) {
            logger.info("enviarCorreo " + e);
            showMessage(FacesMessage.SEVERITY_FATAL, "Error", "Ocurrió un error");
        }
    }

    public void actualizarPassword() {
        logger.info("actualizarCorreo");
        try {
            if (getPassword().equals(getPassword2())) {
                setUserController(new UserController());
                User user = getUserController().getByUserName(getUsernameL());
                setUserHasPermissionController(new UserHasPermissionController());
                // convierto la fecha del link para validarla 
                DateTimeFormatter formato = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
                LocalDateTime fechaConvertida = LocalDateTime.parse(getExpiracionLink(), formato);
                LocalDate fechaActual = LocalDate.now(ZoneId.of("America/Denver"));
                if (!fechaConvertida.toLocalDate().isEqual(fechaActual)) {
                    showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Este link ya ha expirado");
                } else if (getPassword().length() < 5) {
                    showMessage(FacesMessage.SEVERITY_ERROR, "Error", "La contraseña es muy corta");
                } else if (getUserHasPermissionController().updatePassword(user.getId(), new CarDriverSecurity(APP, getPassword()).getPassword())) {
                    showMessage(FacesMessage.SEVERITY_INFO, "Contraseña actualizada", "La contraseña se ha actualizado correctamente ");
                } else {
                    showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Error al actualizar la contraseña");
                }
            } else {
                showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Las contraseñas no coinciden ");
            }
        } catch (Exception e) {
            logger.error("actualizarCorreo " + e);
            showMessage(FacesMessage.SEVERITY_FATAL, "Error", "Ocurrió un error");
        }
    }

    public static String encrypt(String data) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(KEY.getBytes(StandardCharsets.UTF_8), ALGOR);
        Cipher cipher = Cipher.getInstance(ALGOR);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);

        byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getUrlEncoder().withoutPadding().encodeToString(encryptedBytes);
    }

    public static String decrypt(String encryptedData) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(KEY.getBytes(StandardCharsets.UTF_8), ALGOR);
        Cipher cipher = Cipher.getInstance(ALGOR);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);

        byte[] encryptedBytes = Base64.getUrlDecoder().decode(encryptedData);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }

    private boolean resetPasswordEmail(String mail, String link) {
        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 = "Recuperación de contraseña CROV Inmobiliaria";

        String HTMLBODY = "<h1>Actualizar contraseña de acceso</h1>"
                + "<p>Enlace de recuperación: <a href='"+ link +"'>Recuperar contraseña</a></p><br/>"
                + "<p>De clic sobre el enlace adjunto para resetear su contraseña</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 UserController getUserController() {
        return userController;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public CustomerController getCustomerController() {
        return customerController;
    }

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

    public String getPassword2() {
        return password2;
    }

    public void setPassword2(String password2) {
        this.password2 = password2;
    }

    public String getUsernameL() {
        return usernameL;
    }

    public void setUsernameL(String usernameL) {
        this.usernameL = usernameL;
    }

    public String getExpiracionLink() {
        return expiracionLink;
    }

    public void setExpiracionLink(String expiracionLink) {
        this.expiracionLink = expiracionLink;
    }

    public UserHasPermissionController getUserHasPermissionController() {
        return userHasPermissionController;
    }

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

}
