/*
 * 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.apc.web.beans.admin;

import com.arrebol.apc.controller.BitacoraController;
import com.arrebol.apc.controller.GenericController;
import com.arrebol.apc.controller.admin.CustomerController;
import com.arrebol.apc.controller.admin.EndorsementController;
import com.arrebol.apc.controller.admin.LoanController;
import com.arrebol.apc.controller.catalog.LoanTypeController;
import com.arrebol.apc.model.catalog.People;
import com.arrebol.apc.model.core.Office;
import com.arrebol.apc.model.core.User;
import com.arrebol.apc.model.enums.LoanDetailsType;
import com.arrebol.apc.model.enums.LoanRenovationStatus;
import com.arrebol.apc.model.enums.LoanStatus;
import com.arrebol.apc.model.enums.OwnerLoan;
import com.arrebol.apc.model.enums.PeopleType;
import com.arrebol.apc.model.loan.Loan;
import com.arrebol.apc.model.loan.LoanByRenovation;
import com.arrebol.apc.model.loan.LoanByUser;
import com.arrebol.apc.model.loan.LoanByUserId;
import com.arrebol.apc.model.loan.LoanDetails;
import com.arrebol.apc.model.loan.LoanType;
import com.arrebol.apc.model.system.logs.Bitacora;
import com.arrebol.apc.web.beans.Datatable;
import com.arrebol.apc.web.beans.GenericBean;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.primefaces.event.ReorderEvent;
import org.primefaces.event.RowEditEvent;

/**
 *
 * @author Oscar Armando Vargas Cardenas <oscar.vargas@arrebol.com.mx>
 */
@Named("loanPendingManager")
@ViewScoped
public class LoanPendingBean extends GenericBean implements Serializable, Datatable {

   public List<Loan> fillDatatableLoan() {

      return loanCtrl.fillLoanByStatusPendingDatatable(getLoggedUser().getOffice().getId());
   }

   @Override
   public void editRow(RowEditEvent event) {

   }

   public void calculationFunction() {
      if (loanTypeId != null && !loanTypeId.isEmpty()) {
         total = loanTypeCtrl.getLoanTypeById(loanTypeId).getPaymentTotal().add(totalFee).subtract(totalPayment);
      } else {
         total = BigDecimal.ZERO;
      }
   }

   public void approvedLoan() {
      loanCtrl.updateLoanByStatus(LoanStatus.APPROVED, selectedLoan.getId(), getLoggedUser().getUser().getId());
      loanCtrl.updateLoanByUserByStatus(LoanStatus.APPROVED, selectedLoan);
      loan.remove(selectedLoan);
      selectedLoan = null;
      selectedLoan = null;

      showMessage(FacesMessage.SEVERITY_INFO, "Cambio de estatus", "la venta se cambió a estatus 'Aprobado' de forma correcta.");
   }

   @Override
   public void onRowCancel(RowEditEvent event) {
      throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
   }

   @Override
   public void onRowReorder(ReorderEvent event) {
      showMessage(FacesMessage.SEVERITY_INFO, "Registro Movido", "De columna: " + (event.getFromIndex() + 1) + " a columna: " + (event.getToIndex() + 1));
   }

   @Override
   public void addRow() {
      Loan loanSave = new Loan();
      loanSave.setComments(comments);
      loanSave.setCustomer(new People(customerId));
      if (endorsementId != null && !endorsementId.isEmpty() && !endorsementId.equals("0")) {
         loanSave.setEndorsement(new People(endorsementId));
      }
      loanSave.setLoanType(new LoanType(loanTypeId));
      if (aprobado) {
         loanSave.setLoanStatus(LoanStatus.APPROVED);
      } else if (terminado) {
         loanSave.setLoanStatus(LoanStatus.FINISH);
      } else {
         loanSave.setLoanStatus(LoanStatus.PENDING);
      }
      loanSave.setAmountPaid(totalPayment);
      loanSave.setRouteCtlg(customerCtrl.findPeopleById(customerId).getRouteCtlg());
      if (totalPayment.compareTo(BigDecimal.ZERO) == 0 && totalFee.compareTo(BigDecimal.ZERO) == 0) {
         loanSave.setLastReferenceNumber(0);
      }
      if (totalPayment.compareTo(BigDecimal.ZERO) > 0 && totalFee.compareTo(BigDecimal.ZERO) == 0) {
         loanSave.setLastReferenceNumber(1);
      }
      if (totalPayment.compareTo(BigDecimal.ZERO) == 0 && totalFee.compareTo(BigDecimal.ZERO) > 0) {
         loanSave.setLastReferenceNumber(1);
      }
      if (totalPayment.compareTo(BigDecimal.ZERO) > 0 && totalFee.compareTo(BigDecimal.ZERO) > 0) {
         loanSave.setLastReferenceNumber(2);
      }
      loanSave.setAmountToPay(loanTypeCtrl.getLoanTypeById(loanTypeId).getPaymentTotal().add(totalFee));
      loanSave.setCreatedBy(userId);
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(createdOn);
      calendar.set(Calendar.HOUR_OF_DAY, 12);
      calendar.set(Calendar.MINUTE, 0);
      calendar.set(Calendar.SECOND, 0);
      calendar.set(Calendar.MILLISECOND, 0);
      loanSave.setCreatedOn(new Date());
      loanSave.setLastUpdatedOn(new Date());

      if (loanCtrl.saveLoan(loanSave)) {
         Loan temp = loanCtrl.getLoanById(loanSave.getId());
         String userName = "";
         for (User user : users) {
            if (user.getId().equalsIgnoreCase(userId)) {
               userName = user.getHumanResource().getFirstName() + " "
                       + user.getHumanResource().getLastName();
               break;
            }
         }
         Calendar fechaAct = Calendar.getInstance();
         if (fechaAct.before(calendar)) {
            Bitacora bitacora = new Bitacora();
            bitacora.setAction("Compra de producto postfechado");
            bitacora.setCommentsUser("");
            bitacora.setCreatedBy(getLoggedUser().getUser().getId());
            bitacora.setCreatedOn(new Date());
            bitacora.setDescription("El usuario " + userName + " postfechó la venta del cliente " + temp.getCustomer().getFullName()
                    + ", con cantidad de $" + temp.getLoanType().getPayment() + " al día " + temp.getCreatedOn());
            bitacora.setNameUser(getLoggedUser().getUser().getUserName());
            bitacora.setOffice(new Office(getLoggedUser().getOffice().getId()));
            bitacoraCtrl.saveBitacora(bitacora);
         }

         LoanByUser loanByUser = new LoanByUser();
         LoanByUserId idRelation = new LoanByUserId();

         idRelation.setIdLoan(loanSave.getId());
         idRelation.setIdUser(userId);

         loanByUser.setId(idRelation);
         loanByUser.setComments(comments);
         loanByUser.setCreatedBy(getLoggedUser().getUser().getId());
         if (aprobado) {
            loanByUser.setLoanByUserStatus(LoanStatus.APPROVED);
         } else if (terminado) {
            loanByUser.setLoanByUserStatus(LoanStatus.FINISH);
         } else {
            loanByUser.setLoanByUserStatus(LoanStatus.PENDING);
         }
         loanByUser.setLoan(loanSave);
         loanByUser.setOrderInList(0);
         loanByUser.setOwnerLoan(OwnerLoan.CURRENT_OWNER);
         loanByUser.setUser(new User(userId));
         loanCtrl.saveLoanByUser(loanByUser);

         int contador = 1;
         if (totalPayment.compareTo(BigDecimal.ZERO) > 0) {
            LoanDetails detail = new LoanDetails();
            detail.setComments(comments);
            detail.setCreatedBy(getLoggedUser().getUser().getId());
            detail.setCreatedOn(createdOn);
            detail.setLoan(loanSave);
            detail.setLoanDetailsType(LoanDetailsType.PAYMENT);
            detail.setPaymentAmount(totalPayment);
            detail.setPeopleType(PeopleType.CUSTOMER);
            detail.setReferenceNumber(contador);
            detail.setUser(new User(userId));
            if (loanCtrl.saveLoanDetail(detail)) {
               contador++;
            }
         }
         if (totalFee.compareTo(BigDecimal.ZERO) > 0) {
            LoanDetails detail = new LoanDetails();
            detail.setComments(comments);
            detail.setCreatedBy(getLoggedUser().getUser().getId());
            detail.setCreatedOn(createdOn);
            detail.setLoan(loanSave);
            detail.setLoanDetailsType(LoanDetailsType.FEE);
            detail.setPaymentAmount(totalFee);
            detail.setPeopleType(PeopleType.CUSTOMER);
            detail.setReferenceNumber(contador);
            detail.setUser(new User(userId));
            if (loanCtrl.saveLoanDetail(detail)) {
               contador++;
            }
         }

      }
      loan.clear();
      createdOn = new Date();
      comments = "";
      customerId = "";
      endorsementId = "";
      loanTypeId = "";
      userId = "";
      total = BigDecimal.ZERO;
      totalFee = BigDecimal.ZERO;
      totalPayment = BigDecimal.ZERO;
      aprobado = false;
      terminado = false;
      loan = fillDatatableLoan();
      FacesMessage msg = new FacesMessage("Nueva venta", "Se agregó correctamente");
      FacesContext.getCurrentInstance().addMessage(null, msg);
   }

   @Override
   public void deleteRow() {
      loanCtrl.updateLoanByStatus(LoanStatus.REJECTED, selectedLoan.getId(), getLoggedUser().getUser().getId());
      loanCtrl.updateLoanByUserByStatus(LoanStatus.REJECTED, selectedLoan);

      LoanByRenovation renovation;
      renovation = loanCtrl.getLoanByRenovationByIdLoanNew(selectedLoan);
      if (renovation != null) {
         loanCtrl.updateLoanByRenovationByStatus(LoanRenovationStatus.REJECTED, selectedLoan, getLoggedUser().getUser().getId());
         loanCtrl.updateLoanByStatus(LoanStatus.APPROVED, renovation.getLoanOld().getId(), getLoggedUser().getUser().getId());
         loanCtrl.updateLoanByUserByStatus(LoanStatus.APPROVED, renovation.getLoanOld());
      }
      loan.remove(selectedLoan);
      selectedLoan = null;
      showMessage(FacesMessage.SEVERITY_INFO, "Cambio de estatus", "la venta se cambió a estatus 'Rechazado' de forma correcta.");
   }

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

   public LoanController getLoanCtrl() {
      return loanCtrl;
   }

   public void setLoanCtrl(LoanController loanCtrl) {
      this.loanCtrl = loanCtrl;
   }

   public List<Loan> getLoan() {
      return loan;
   }

   public void setLoan(List<Loan> loan) {
      this.loan = loan;
   }

   public Loan getSelectedLoan() {
      return selectedLoan;
   }

   public void setSelectedLoan(Loan selectedLoan) {
      this.selectedLoan = selectedLoan;
   }

   public CustomerController getCustomerCtrl() {
      return customerCtrl;
   }

   public void setCustomerCtrl(CustomerController customerCtrl) {
      this.customerCtrl = customerCtrl;
   }

   public EndorsementController getEndorsementCtrl() {
      return endorsementCtrl;
   }

   public void setEndorsementCtrl(EndorsementController endorsementCtrl) {
      this.endorsementCtrl = endorsementCtrl;
   }

   public LoanTypeController getLoanTypeCtrl() {
      return loanTypeCtrl;
   }

   public void setLoanTypeCtrl(LoanTypeController loanTypeCtrl) {
      this.loanTypeCtrl = loanTypeCtrl;
   }

   public List<People> getCustomer() {
      return customer;
   }

   public void setCustomer(List<People> customer) {
      this.customer = customer;
   }

   public List<People> getEndorsement() {
      return endorsement;
   }

   public void setEndorsement(List<People> endorsement) {
      this.endorsement = endorsement;
   }

   public List<LoanType> getLoanType() {
      return loanType;
   }

   public void setLoanType(List<LoanType> loanType) {
      this.loanType = loanType;
   }

   public String getCustomerId() {
      return customerId;
   }

   public void setCustomerId(String customerId) {
      this.customerId = customerId;
   }

   public String getEndorsementId() {
      return endorsementId;
   }

   public void setEndorsementId(String endorsementId) {
      this.endorsementId = endorsementId;
   }

   public String getLoanTypeId() {
      return loanTypeId;
   }

   public void setLoanTypeId(String loanTypeId) {
      this.loanTypeId = loanTypeId;
   }

   public String getComments() {
      return comments;
   }

   public void setComments(String comments) {
      this.comments = comments;
   }

   public List<User> getUsers() {
      return users;
   }

   public void setUsers(List<User> users) {
      this.users = users;
   }

   public String getUserId() {
      return userId;
   }

   public void setUserId(String userId) {
      this.userId = userId;
   }

   public GenericController getGenericCtrl() {
      return genericCtrl;
   }

   public void setGenericCtrl(GenericController genericCtrl) {
      this.genericCtrl = genericCtrl;
   }

   public Date getCreatedOn() {
      return createdOn;
   }

   public void setCreatedOn(Date createdOn) {
      this.createdOn = createdOn;
   }

   public BigDecimal getTotalPayment() {
      return totalPayment;
   }

   public void setTotalPayment(BigDecimal totalPayment) {
      this.totalPayment = totalPayment;
   }

   public BigDecimal getTotalFee() {
      return totalFee;
   }

   public void setTotalFee(BigDecimal totalFee) {
      this.totalFee = totalFee;
   }

   public BigDecimal getTotal() {
      return total;
   }

   public void setTotal(BigDecimal total) {
      this.total = total;
   }

   public boolean isAprobado() {
      return aprobado;
   }

   public void setAprobado(boolean aprobado) {
      this.aprobado = aprobado;
   }

   public boolean isTerminado() {
      return terminado;
   }

   public void setTerminado(boolean terminado) {
      this.terminado = terminado;
   }

   private LoanController loanCtrl;
   private CustomerController customerCtrl;
   private EndorsementController endorsementCtrl;
   private LoanTypeController loanTypeCtrl;
   private GenericController genericCtrl;

   private List<Loan> loan;
   private Loan selectedLoan;
   private String comments;

   private List<People> customer;
   private List<People> endorsement;
   private List<LoanType> loanType;
   private List<User> users;

   private String customerId;
   private String endorsementId;
   private String loanTypeId;
   private String userId;

   private Date createdOn;
   private BigDecimal totalPayment;
   private BigDecimal totalFee;
   private BigDecimal total;
   private boolean aprobado;
   private boolean terminado;

   private BitacoraController bitacoraCtrl;

   @PostConstruct
   public void init() {
      loanCtrl = new LoanController();
      customerCtrl = new CustomerController();
      endorsementCtrl = new EndorsementController();
      loanTypeCtrl = new LoanTypeController();
      genericCtrl = new GenericController();
      totalPayment = BigDecimal.ZERO;
      totalFee = BigDecimal.ZERO;
      total = BigDecimal.ZERO;
      aprobado = false;
      terminado = false;
      bitacoraCtrl = new BitacoraController();

      customer = customerCtrl.fillCustomersDatatable(getLoggedUser().getOffice().getId());
      endorsement = endorsementCtrl.fillEndorsementsDatatable(getLoggedUser().getOffice().getId());
      loanType = loanTypeCtrl.fillLoanTypeDatatable(getLoggedUser().getOffice().getId());
      users = genericCtrl.getAllUsersByOffice(getLoggedUser().getOffice().getId());

      loan = fillDatatableLoan();
   }

}
