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

import com.arrebol.taxiservicios.beans.TaxiGenericBean;
import com.arrebol.taxiservicios.controller.catalog.UserLocationController;
import com.arrebol.taxiservicios.controller.catalog.UserOpenPayController;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.catalog.LocationPaquetes;
import com.arrebol.taxiservicios.model.catalog.UserLocation;
import com.arrebol.taxiservicios.model.catalog.UserOpenPay;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import mx.openpay.client.Card;
import mx.openpay.client.Customer;
import mx.openpay.client.core.OpenpayAPI;
import mx.openpay.client.exceptions.OpenpayServiceException;
import mx.openpay.client.exceptions.ServiceUnavailableException;
import mx.openpay.client.utils.SearchParams;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

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

    private static final OpenpayAPI api = new OpenpayAPI("https://sandbox-api.openpay.mx", "sk_6310ee6c56c842a892b238eb3fc31eda", "m1al82yn7h3mdonrkdfe");

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

    private UserOpenPayController userOpenPayController;
    private UserLocationController userLocationController;

    private List<LocationPaquetes> listLocationPaquetes;
    private List<UserLocation> listUserLocation;
    private List<Card> cardsOpenPay;
    private List<UserOpenPay> listUserOpenPay;

    private UserOpenPay selectUserOpenPay;
    private UserLocation selectUserLocation;
    private String selectLocation;
    private String selectTargeta;

    private String deviceSessionId;
    private String cardTitular;
    private String cardTarjeta;
    private String cardDireccionCiudad;
    private String cardDireccionEstado;
    private String cardDireccionCalle;
    private String cardDireccionCodigoPostal;
    private String cardDireccionNumero;
    private Integer cardExpiracionMes;
    private Integer cardExpiracionAno;
    private String cardDigitos;

    private Boolean pagoAutomatico;
    private Boolean actualizandoPagoAutomatico;
    private Boolean LocacionDemo; 

    @PostConstruct
    public void init() {
        logger.info("init");
        try {
            // se cargan las locasiones del usuario
            setUserLocationController(new UserLocationController());
            setListUserLocation(getUserLocationController().fillAllUserLocationByUser(getLoggedUser()));
            cargarDatosTarjetaOp();
            setActualizandoPagoAutomatico(false);
            setLocacionDemo(false);
            // se valida si la locasion es DEMO
 
            // Se verifica si está activado el pago automático
            if (getListUserLocation().get(0).getPagoAutomatico() == 1) {
                setPagoAutomatico(true);
            } else {
                setPagoAutomatico(false);
            }
        } catch (Exception e) {
            logger.error("init", e);
        }
    }

    private void cargarDatosTarjetaOp() {
        logger.info("cargarDatosTarjetaOp");
        try {
            // Datos de conexion OpenPay

            // Se cargan los datos de la tegeta desde OpenPay
            setUserOpenPayController(new UserOpenPayController());
            setListUserOpenPay(new ArrayList<>());
            UserOpenPay us = getUserOpenPayController().fillUserOpenPayByUser(getLoggedUser());
            Card card = api.cards().get(us.getIdClienteOpenPay(), us.getIdTargetaOpenPay());
            us.setDescripsionTargeta(card.getCardNumber() + " " + card.getBankName() + " " + card.getType());
            us.setTitularTarjeta(card.getHolderName());
            getListUserOpenPay().add(us);
        } catch (OpenpayServiceException | ServiceUnavailableException e) {
            logger.error("Error al cargar los datos de la tarjeta " + e);
        }
    }

    public void cargarTargetas() {
        logger.info("cargarTargetas");
        try {
            // busco al UserOpenPay
            setUserOpenPayController(new UserOpenPayController());
            UserOpenPay userOp = getUserOpenPayController().fillUserOpenPayByUser(getLoggedUser());
            //tagetas
            SearchParams request = new SearchParams();
            request.offset(0);
            request.limit(100);
            setCardsOpenPay(api.cards().list(userOp.getIdClienteOpenPay(), request));
        } catch (OpenpayServiceException | ServiceUnavailableException e) {
            logger.error("Error al cargar las tarjetas" + e);
        }
    }

    public void comprarSuscripcion() {
        logger.info("comprarSuscripcion");
        try {
            // Se valida si ahí una actualización en proceso
            if (!getActualizandoPagoAutomatico()) {
                setActualizandoPagoAutomatico(true);
                setUserLocationController(new UserLocationController());
                // Se actualizan todas las locaciones del usuario
                for (UserLocation usLo : getListUserLocation()) {
                    if (getPagoAutomatico()) {
                        usLo.setPagoAutomatico(1);
                    } else {
                        usLo.setPagoAutomatico(0);
                    }
                }
                setListUserLocation(getUserLocationController().fillAllUserLocationByUser(getLoggedUser()));
                if(getPagoAutomatico()){
                    showMessage(FacesMessage.SEVERITY_INFO, "Pago automático activado", "El pago automático se ha actualizado, ahora los cobros se revisaron de manera automática una vez finalice el plan");
                }else{
                    showMessage(FacesMessage.SEVERITY_INFO, "Pago automático desactivado", "El pago automático sé a desactivado, ahora los pagos deberán hacerse de manera manual una vez finalice el paquete activo ");
                }
                setActualizandoPagoAutomatico(false);
                logger.error("Pago automático actualizado");
            }else{
                 logger.info("Actualizado pago automático");
            }
        } catch (Exception e) {
            setActualizandoPagoAutomatico(false);
            showMessage(FacesMessage.SEVERITY_ERROR, "Error ", "Ocurrió un error al actualizar el pago automático ");
            logger.error("Error openpay: " + e);
        }
    }

    public void registrarNuevaTarjeta() {
        logger.info("RegistrarNuevaTarjeta");
        try {
            // busco al UserOpenPay
            setUserOpenPayController(new UserOpenPayController());
            UserOpenPay userOp = getUserOpenPayController().fillUserOpenPayByUser(getLoggedUser());
            // se carga a el usuario desde OpenPay
            Customer cus = api.customers().get(userOp.getIdClienteOpenPay());
            // se crea la nueva targeta
            Card card = new Card();
            card.holderName(getCardTitular());
            card.cardNumber(getCardTarjeta());
            card.cvv2(getCardDigitos());
            card.expirationMonth(getCardExpiracionMes());
            card.expirationYear(getCardExpiracionAno());
            card.setDeviceSessionId(getDeviceSessionId());
            card.address(cus.getAddress());
            api.cards().create(cus.getId(), card);
            showMessage(FacesMessage.SEVERITY_INFO, "Tarjeta agregada", "La tarjeta se agregó correctamente");
            logger.error("La tarjeta se agregó correctamente a OpenPay");
        } catch (OpenpayServiceException | ServiceUnavailableException e) {
            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 actualizarTarjeta() {
        logger.info("actualizarTarjeta");
        try {
            // se actulisa la tageta 
            setUserOpenPayController(new UserOpenPayController());
            getSelectUserOpenPay().setIdTargetaOpenPay(getSelectTargeta());
            getUserOpenPayController().addUserOpenPay(getSelectUserOpenPay(), getLoggedUser(), false);
            // se carga los datos de la targeta desde OpenPay
            cargarDatosTarjetaOp();
            showMessage(FacesMessage.SEVERITY_INFO, "Tarjeta actualizada", "Tarjeta actualizada correctamente");
            logger.info("Tarjeta actualizada correctamente");
        } catch (Exception e) {
            showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Ocurrió un error al actualizar la tarjeta");
            logger.error("Error al actualizar las tarjetas" + e);
        }
    }

    public UserOpenPayController getUserOpenPayController() {
        return userOpenPayController;
    }

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

    public UserLocationController getUserLocationController() {
        return userLocationController;
    }

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

    public List<LocationPaquetes> getListLocationPaquetes() {
        return listLocationPaquetes;
    }

    public void setListLocationPaquetes(List<LocationPaquetes> listLocationPaquetes) {
        this.listLocationPaquetes = listLocationPaquetes;
    }

    public List<UserLocation> getListUserLocation() {
        return listUserLocation;
    }

    public void setListUserLocation(List<UserLocation> listUserLocation) {
        this.listUserLocation = listUserLocation;
    }

    public String getSelectLocation() {
        return selectLocation;
    }

    public void setSelectLocation(String selectLocation) {
        this.selectLocation = selectLocation;
    }

    public UserOpenPay getSelectUserOpenPay() {
        return selectUserOpenPay;
    }

    public void setSelectUserOpenPay(UserOpenPay selectUserOpenPay) {
        this.selectUserOpenPay = selectUserOpenPay;
    }

    public List<Card> getCardsOpenPay() {
        return cardsOpenPay;
    }

    public void setCardsOpenPay(List<Card> cardsOpenPay) {
        this.cardsOpenPay = cardsOpenPay;
    }

    public List<UserOpenPay> getListUserOpenPay() {
        return listUserOpenPay;
    }

    public void setListUserOpenPay(List<UserOpenPay> listUserOpenPay) {
        this.listUserOpenPay = listUserOpenPay;
    }

    public UserLocation getSelectUserLocation() {
        return selectUserLocation;
    }

    public void setSelectUserLocation(UserLocation selectUserLocation) {
        this.selectUserLocation = selectUserLocation;
    }

    public String getSelectTargeta() {
        return selectTargeta;
    }

    public void setSelectTargeta(String selectTargeta) {
        this.selectTargeta = selectTargeta;
    }

    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 String getCardDireccionCiudad() {
        return cardDireccionCiudad;
    }

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

    public String getCardDireccionEstado() {
        return cardDireccionEstado;
    }

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

    public String getCardDireccionCalle() {
        return cardDireccionCalle;
    }

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

    public String getCardDireccionCodigoPostal() {
        return cardDireccionCodigoPostal;
    }

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

    public String getCardDireccionNumero() {
        return cardDireccionNumero;
    }

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

    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 Boolean getPagoAutomatico() {
        return pagoAutomatico;
    }

    public void setPagoAutomatico(Boolean pagoAutomatico) {
        this.pagoAutomatico = pagoAutomatico;
    }

    public Boolean getActualizandoPagoAutomatico() {
        return actualizandoPagoAutomatico;
    }

    public void setActualizandoPagoAutomatico(Boolean actualizandoPagoAutomatico) {
        this.actualizandoPagoAutomatico = actualizandoPagoAutomatico;
    }

    public Boolean getLocacionDemo() {
        return LocacionDemo;
    }

    public void setLocacionDemo(Boolean LocacionDemo) {
        this.LocacionDemo = LocacionDemo;
    }

}
