package bean;

import beans.CuentaCorrienteFacadeLocal;
import beans.TarjetaDebitoFacadeLocal;
import beans.TransferenciaCuentaCorrienteFacadeLocal;
import beans.TransferenciaTarjetaDebitoFacadeLocal;
import entities.CuentaCorriente;
import entities.TarjetaDebito;
import entities.TransferenciaCuentaCorriente;
import entities.TransferenciaTarjetaDebito;
import java.io.Serializable;
import java.util.Date;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Named;

@Named(value = "transferenciaBean")
@SessionScoped
public class TransferenciaBean implements Serializable {

  @EJB
  private TransferenciaCuentaCorrienteFacadeLocal transferenciaCCFacade;
  @EJB
  private TransferenciaTarjetaDebitoFacadeLocal transferenciaTDFacade;
  @EJB
  private CuentaCorrienteFacadeLocal cuentaCorrienteFacade;
  @EJB
  private TarjetaDebitoFacadeLocal tarjetaDebitoFacade;

  private int monto;
  private int destinatario_id;
  private String comentario;
  private CuentaCorriente cuentaCorriente;
  private TarjetaDebito tarjetaDebito;
  private TransferenciaCuentaCorriente transferenciaCuentaCorriente;
  private TransferenciaTarjetaDebito transferenciaTarjetaDebito;

  public String transferir() {
    if (cuentaCorriente != null) {
      return transferirEnCuentaCorriente();
    } else if (tarjetaDebito != null) {
      return transferirEnTarjetaDebito();
    } else {
      return null;
    }
  }

  public String transferirEnCuentaCorriente() {
    if (this.destinatario_id == this.cuentaCorriente.getId()) {
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("No se puede transferir hacia si mismo"));
      FacesContext.getCurrentInstance().validationFailed();
      return "cliente_cuenta_corriente_transferir";
    }

    CuentaCorriente destinatario = cuentaCorrienteFacade.find(this.destinatario_id);
    if (destinatario == null) {
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("La cuenta corriente ingresada no existe"));
      FacesContext.getCurrentInstance().validationFailed();
      return "cliente_cuenta_corriente_transferir";
    }

    if (cuentaCorriente.getSaldo() - monto < 0) {
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("El monto sobrepasa el saldo de la cuenta corriente"));
      FacesContext.getCurrentInstance().validationFailed();
      return "cliente_cuenta_corriente_transferir";
    }

    TransferenciaCuentaCorriente transferencia = new TransferenciaCuentaCorriente();
    transferencia.setComentario(comentario);
    transferencia.setMonto(monto);
    transferencia.setCuentaCorrienteFrom(cuentaCorriente);
    transferencia.setCuentaCorrienteTo(destinatario);

    cuentaCorriente.setSaldo(cuentaCorriente.getSaldo() - monto);
    destinatario.setSaldo(destinatario.getSaldo() + monto);

    transferenciaCCFacade.create(transferencia);
    cuentaCorrienteFacade.edit(cuentaCorriente);
    cuentaCorrienteFacade.edit(destinatario);

    resetInput();
    return "cliente_cuenta_corriente_view";
  }

  public String transferirEnTarjetaDebito() {
    if (this.destinatario_id == this.tarjetaDebito.getId()) {
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("No se puede transferir hacia si mismo"));
      FacesContext.getCurrentInstance().validationFailed();
      return "cliente_tarjeta_debito_transferir";
    }

    TarjetaDebito destinatario = tarjetaDebitoFacade.find(this.destinatario_id);
    if (destinatario == null) {
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("La tarjeta de debito ingresada no existe"));
      FacesContext.getCurrentInstance().validationFailed();
      return "cliente_tarjeta_debito_transferir";
    }

    if (tarjetaDebito.getSaldo() - monto < 0) {
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("El monto sobrepasa el saldo de la tarjeta de debito"));
      FacesContext.getCurrentInstance().validationFailed();
      return "cliente_tarjeta_debito_transferir";
    }

    TransferenciaTarjetaDebito transferencia = new TransferenciaTarjetaDebito();
    transferencia.setComentario(comentario);
    transferencia.setMonto(monto);
    transferencia.setTarjetaDebitoFrom(tarjetaDebito);
    transferencia.setTarjetaDebitoTo(destinatario);

    tarjetaDebito.setSaldo(tarjetaDebito.getSaldo() - monto);
    destinatario.setSaldo(destinatario.getSaldo() + monto);

    transferenciaTDFacade.create(transferencia);
    tarjetaDebitoFacade.edit(tarjetaDebito);
    tarjetaDebitoFacade.edit(destinatario);

    resetInput();
    return "cliente_tarjeta_debito_view";
  }

  public String eliminarTransferenciaEnCuentaCorriente() {
    CuentaCorriente ccFrom = transferenciaCuentaCorriente.getCuentaCorrienteFrom();
    CuentaCorriente ccTo = transferenciaCuentaCorriente.getCuentaCorrienteTo();

    if (ccTo.getSaldo() - transferenciaCuentaCorriente.getMonto() < 0) {
      FacesContext facesContext = FacesContext.getCurrentInstance();
      facesContext.addMessage(null, new FacesMessage("Eliminar la transferencia dejaria la cuenta del destinatario en negativo"));
      facesContext.validationFailed();
      return "admin_cuenta_corriente_delete_transferencia";
    }

    ccFrom.setSaldo(ccFrom.getSaldo() + transferenciaCuentaCorriente.getMonto());
    ccTo.setSaldo(ccTo.getSaldo() - transferenciaCuentaCorriente.getMonto());

    ccFrom.getTransferenciaFromList().remove(transferenciaCuentaCorriente);
    ccTo.getTransferenciaToList().remove(transferenciaCuentaCorriente);

    transferenciaCCFacade.remove(transferenciaCuentaCorriente);
    cuentaCorrienteFacade.edit(ccFrom);
    cuentaCorrienteFacade.edit(ccTo);
    
    return "admin_cuenta_corriente_view";
  }


  public String eliminarTransferenciaEnTarjetaDebito() {
    TarjetaDebito tdFrom = transferenciaTarjetaDebito.getTarjetaDebitoFrom();
    TarjetaDebito tdTo = transferenciaTarjetaDebito.getTarjetaDebitoTo();

    if (tdTo.getSaldo() - transferenciaTarjetaDebito.getMonto() < 0) {
      FacesContext facesContext = FacesContext.getCurrentInstance();
      facesContext.addMessage(null, new FacesMessage("Eliminar la transferencia dejaria la cuenta del destinatario en negativo"));
      facesContext.validationFailed();
      return "admin_tarjeta_debito_delete_transferencia";
    }

    tdFrom.setSaldo(tdFrom.getSaldo() + transferenciaTarjetaDebito.getMonto());
    tdTo.setSaldo(tdTo.getSaldo() - transferenciaTarjetaDebito.getMonto());

    tdFrom.getTransferenciaFromList().remove(transferenciaTarjetaDebito);
    tdTo.getTransferenciaToList().remove(transferenciaTarjetaDebito);

    transferenciaTDFacade.remove(transferenciaTarjetaDebito);
    tarjetaDebitoFacade.edit(tdFrom);
    tarjetaDebitoFacade.edit(tdTo);
    
    return "admin_tarjeta_debito_view";
  }

  private void resetInput() {
    this.cuentaCorriente = null;
    this.tarjetaDebito = null;
    this.monto = 0;
    this.destinatario_id = 0;
    this.comentario = "";
  }

  public int getMonto() {
    return monto;
  }

  public void setMonto(int monto) {
    this.monto = monto;
  }

  public String getComentario() {
    return comentario;
  }

  public void setComentario(String comentario) {
    this.comentario = comentario;
  }

  public CuentaCorriente getCuentaCorriente() {
    return cuentaCorriente;
  }

  public void setCuentaCorriente(CuentaCorriente cuentaCorriente) {
    this.cuentaCorriente = cuentaCorriente;
  }

  public TarjetaDebito getTarjetaDebito() {
    return tarjetaDebito;
  }

  public void setTarjetaDebito(TarjetaDebito tarjetaDebito) {
    this.tarjetaDebito = tarjetaDebito;
  }

  public int getDestinatario_id() {
    return destinatario_id;
  }

  public void setDestinatario_id(int destinatario_id) {
    this.destinatario_id = destinatario_id;
  }

  public TransferenciaCuentaCorriente getTransferenciaCuentaCorriente() {
    return transferenciaCuentaCorriente;
  }

  public void setTransferenciaCuentaCorriente(TransferenciaCuentaCorriente transferenciaCuentaCorriente) {
    this.transferenciaCuentaCorriente = transferenciaCuentaCorriente;
  }

  public TransferenciaTarjetaDebito getTransferenciaTarjetaDebito() {
    return transferenciaTarjetaDebito;
  }

  public void setTransferenciaTarjetaDebito(TransferenciaTarjetaDebito transferenciaTarjetaDebito) {
    this.transferenciaTarjetaDebito = transferenciaTarjetaDebito;
  }
  
  
}
