/*
 * 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.GenericController;
import com.arrebol.apc.controller.admin.LoanController;
import com.arrebol.apc.controller.catalog.LoanTypeController;
import com.arrebol.apc.controller.catalog.RouteController;
import com.arrebol.apc.controller.util.DateWrapper;
import com.arrebol.apc.model.catalog.RouteCtlg;
import com.arrebol.apc.model.core.User;
import com.arrebol.apc.model.enums.ActiveStatus;
import com.arrebol.apc.model.enums.LoanStatus;
import com.arrebol.apc.model.loan.Loan;
import com.arrebol.apc.model.loan.LoanType;
import com.arrebol.apc.model.views.HistoryLoanView;
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.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("loanHistoryManager")
@ViewScoped
public class LoanHistoryBean extends GenericBean implements Serializable, Datatable {

    public void searchHistoricalAction() {
        try {
            if (getStarDate().after(getEndDate())) {
               showMessage(FacesMessage.SEVERITY_ERROR, getBundlePropertyFile().getString("generic.start.date"), getBundlePropertyFile().getString("generic.end.date.error"));
            } else {
                setLoan(getLoanCtrl().fillAllLoansViewDatatable(getStarDate(), getEndDate()));
            }
        } catch (Exception e) {
        }
    }

    public List<HistoryLoanView> fillDatatableLoan() {
        return getLoanCtrl().fillAllLoansViewDatatable(getStarDate(), getEndDate());
    }

    public void changeBonusNewCustomer() {
        loanCtrl.updateBonusNewCustomer(ActiveStatus.ENEBLED, selectedLoan.getId(), getLoggedUser().getUser().getId());
        loan.clear();
        loan = fillDatatableLoan();
        selectedLoan = null;

        showMessage(FacesMessage.SEVERITY_INFO, "Cambio de bono", "El préstamo empezó a contar como bono de cliente nuevo.");
    }

    public void removeBonusNewCustomer() {
        loanCtrl.updateBonusNewCustomer(ActiveStatus.DISABLED, selectedLoan.getId(), getLoggedUser().getUser().getId());
        loan.clear();
        loan = fillDatatableLoan();
        selectedLoan = null;

        showMessage(FacesMessage.SEVERITY_INFO, "Cambio de bono", "El préstamo ya no contará como bono de cliente nuevo.");
    }

    public void deleteFeeLoan() {

        /* if (selectedLoan.getEstatusPrestamo()== LoanStatus.APPROVED.getValue() || selectedLoan.getEstatusPrestamo() == LoanStatus.PENDING_RENOVATION.getValue()) {
            
            List<LoanDetails> details = loanCtrl.getLoanDetailsFeeCurdatebyIdLoan(selectedLoan.getId());
        if (details != null && !details.isEmpty()) {
            Loan loanUpdate = loanCtrl.getLoanById(selectedLoan.getId());
            for (LoanDetails detail : details) {
                loanUpdate.setAmountToPay(loanUpdate.getAmountToPay().subtract(detail.getPaymentAmount()));
            }
            if (loanCtrl.deleteLoanDetailsFeeByLoanCurdate(selectedLoan)) {
                loanCtrl.deleteLoanFeeNotificationByLoanCurdate(selectedLoan);
                loanCtrl.updateLoan(loanUpdate);
                loan.clear();
                loan = fillDatatableLoan();
                selectedLoan = null;
                showMessage(FacesMessage.SEVERITY_INFO, "Multas eliminadas", "Se eliminó el/las multas del día de hoy correctamente.");
            }
        } else {
            showMessage(FacesMessage.SEVERITY_WARN, "Advertencia", "El préstamo no tiene registrado multas el día de hoy");
        }
        }
        else
        {
           showMessage(FacesMessage.SEVERITY_WARN, "No se puede eliminar la multa", "Solo puedes eliminar la multa de préstamos en estatus Aprobados o Pendiente por renovación");
            return; 
        }*/
    }

    public void changeRoute() {
        if (!routeId.isEmpty()) {
            if (loanCtrl.updateRouteById(new RouteCtlg(routeId), selectedLoan.getId(), getLoggedUser().getUser().getId())) {
                showMessage(FacesMessage.SEVERITY_INFO, "Ruta modificada", "Se modificó correctamente.");
            } else {
                showMessage(FacesMessage.SEVERITY_WARN, "Ruta modificada", "Ocurrió un error durante el proceso.");
            }

        }
    }

    public void changeLoanType() {
        if (selectedLoan.getEstatusPrestamo() != LoanStatus.TO_DELIVERY.getValue()) {
            loanTypeId = "";
            selectedLoan = null;
            showMessage(FacesMessage.SEVERITY_WARN, "No se puede cambiar el tipo de préstamo", "Solo puedes cambiar el monto a prestar de préstamos en estatus Por liberar");
            return;
        }
        Loan loanUpdate = loanCtrl.getLoanById(selectedLoan.getId());
        loanUpdate.setLoanType(new LoanType(loanTypeId));
        loanUpdate.setAmountToPay(loanTypeCtrl.getLoanTypeById(loanTypeId).getPaymentTotal());
        if (loanCtrl.updateLoan(loanUpdate)) {
            loan.clear();
            loan = fillDatatableLoan();
            loanTypeId = "";
            selectedLoan = null;
            showMessage(FacesMessage.SEVERITY_INFO, "Cambio de tipo de préstamo", "El préstamo se cambió correctamente");
        }

    }

    public void deleteLoan() {
        /*    loanCtrl.updateLoanByStatusWeb(LoanStatus.DELETED, selectedLoan.getId(), getLoggedUser().getUser().getId());
        loanCtrl.updateLoanByUserByStatus(LoanStatus.DELETED, selectedLoan);
        loan.remove(selectedLoan);
        selectedLoan = null;

        showMessage(FacesMessage.SEVERITY_INFO, "Cambio de estatus", "El préstamo se cambió a estatus 'Eliminado' de forma correcta.");*/
    }

    public void changeApprovedStatus() {
        /*loanCtrl.updateLoanByStatusWeb(LoanStatus.APPROVED, selectedLoan.getId(), getLoggedUser().getUser().getId());
        loanCtrl.updateLoanByUserByStatus(LoanStatus.APPROVED, selectedLoan);
        loan.clear();
        loan = fillDatatableLoan();
        selectedLoan = null;

        showMessage(FacesMessage.SEVERITY_INFO, "Cambio de estatus", "El préstamo se cambió a estatus 'Aprobado' de forma correcta.");*/
    }

    public void changeFinishStatus() {
        /*loanCtrl.updateLoanByStatusWeb(LoanStatus.FINISH, selectedLoan.getId(), getLoggedUser().getUser().getId());
        loanCtrl.updateLoanByUserByStatus(LoanStatus.FINISH, selectedLoan);
        loan.clear();
        loan = fillDatatableLoan();
        selectedLoan = null;

        showMessage(FacesMessage.SEVERITY_INFO, "Cambio de estatus", "El préstamo se cambió a estatus 'Aprobado' de forma correcta.");*/
    }

    public void deletePaymentLoan() {

        /*if (selectedLoan.getLoanStatus() == LoanStatus.APPROVED || selectedLoan.getLoanStatus() == LoanStatus.PENDING_RENOVATION) {
            
            List<LoanDetails> details = loanCtrl.getLoanDetailsCurdatebyIdLoan(selectedLoan.getId());
        if (details != null && !details.isEmpty()) {
            Loan loanUpdate = loanCtrl.getLoanById(selectedLoan.getId());
            for (LoanDetails detail : details) {
                loanUpdate.setAmountPaid(loanUpdate.getAmountPaid().subtract(detail.getPaymentAmount()));
                loanUpdate.setLastReferenceNumber(loanUpdate.getLastReferenceNumber() - 1);
            }
            if (loanCtrl.deleteLoanDetailsByLoanCurdate(selectedLoan)) {
                loanCtrl.updateLoan(loanUpdate);
                loan.clear();
                loan = fillDatatableLoan();
                selectedLoan = null;
                showMessage(FacesMessage.SEVERITY_INFO, "Abonos eliminados", "Se eliminó el/los abonos del día de hoy correctamente.");
            }
        } else {
            showMessage(FacesMessage.SEVERITY_WARN, "Advertencia", "El préstamo no tiene registrado abonos el día de hoy");
        }
        }
        else
        {
           showMessage(FacesMessage.SEVERITY_WARN, "No se puede eliminar abono", "Solo puedes eliminar el abono de préstamos en estatus Aprobados o Pendiente por renovación");
            return; 
        }*/
    }

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

    public void addPayment() {
        /*if (selectedLoan.getLoanStatus() == LoanStatus.APPROVED || selectedLoan.getLoanStatus() == LoanStatus.PENDING_RENOVATION) {
            LoanDetails detail = new LoanDetails();
            detail.setComments(comments);
            detail.setCreatedBy(getLoggedUser().getUser().getId());
            detail.setCreatedOn(new Date());
            detail.setLoan(selectedLoan);
            detail.setLoanDetailsType(LoanDetailsType.PAYMENT);
            detail.setPaymentAmount(payment);
            detail.setPeopleType(PeopleType.CUSTOMER);
            detail.setReferenceNumber(selectedLoan.getLastReferenceNumber() + 1);
            detail.setUser(new User(userId));
            if (loanCtrl.saveLoanDetail(detail)) {
                Loan loanUpdate = loanCtrl.getLoanById(selectedLoan.getId());
                loanUpdate.setAmountPaid(loanUpdate.getAmountPaid().add(payment));
                loanUpdate.setLastReferenceNumber(loanUpdate.getLastReferenceNumber() + 1);
                if (loanUpdate.getAmountToPay().compareTo(loanUpdate.getAmountPaid()) == 0) {

                    LoanByUser loanByUser = loanCtrl.getLoanByUserByIdLoan(loanUpdate);
                    loanByUser.setLoanByUserStatus(LoanStatus.FINISH);
                    if (loanCtrl.updateLoanByUser(loanByUser)) {
                        loanUpdate.setLoanStatus(LoanStatus.FINISH);
                    }
                }
                loanCtrl.updateLoan(loanUpdate);
                loan.clear();
                loan = fillDatatableLoan();
                selectedLoan = null;
                userId = "";
                comments = "";
                payment = BigDecimal.ZERO;
                showMessage(FacesMessage.SEVERITY_INFO, "Agregar abono", "Se agregó el abono de forma correcta.");
            }
        } else {
            selectedLoan = null;
            userId = "";
            comments = "";
            payment = BigDecimal.ZERO;
            showMessage(FacesMessage.SEVERITY_WARN, "No se puede abonar", "Solo puedes abonar préstamos en estatus Aprobados o Pendientes por renovación");
            return;
        }*/

    }

    public void addFee() {
        /*if (selectedLoan.getLoanStatus() != LoanStatus.APPROVED) {
            selectedLoan = null;
            userId = "";
            comments = "";
            fee = BigDecimal.ZERO;
            showMessage(FacesMessage.SEVERITY_WARN, "No se puede multar", "Solo puedes multar préstamos en estatus Aprobados");
            return;
        }
        LoanDetails detail = new LoanDetails();
        detail.setComments(comments);
        detail.setCreatedBy(getLoggedUser().getUser().getId());
        detail.setCreatedOn(new Date());
        detail.setLoan(selectedLoan);
        detail.setLoanDetailsType(LoanDetailsType.FEE);
        detail.setPaymentAmount(fee);
        detail.setPeopleType(PeopleType.CUSTOMER);
        detail.setReferenceNumber(selectedLoan.getLastReferenceNumber() + 1);
        detail.setUser(new User(userId));
        if (loanCtrl.saveLoanDetail(detail)) {
            Loan loanUpdate = loanCtrl.getLoanById(selectedLoan.getId());
            loanUpdate.setAmountToPay(loanUpdate.getAmountToPay().add(fee));
            loanUpdate.setLastReferenceNumber(loanUpdate.getLastReferenceNumber() + 1);
            loanCtrl.updateLoan(loanUpdate);

            LoanFeeNotification notification = new LoanFeeNotification();
            notification.setCreatedBy(getLoggedUser().getUser().getId());
            notification.setCreatedOn(new Date());
            notification.setLoan(loanUpdate);
            notification.setUser(new User(userId));
            notification.setNotificationNumber(loanUpdate.getTotalFeeByLoan() + 1);
            loanCtrl.saveLoanNotificationFee(notification);

            loan.clear();
            loan = fillDatatableLoan();
            selectedLoan = null;
            userId = "";
            comments = "";
            fee = BigDecimal.ZERO;
            showMessage(FacesMessage.SEVERITY_INFO, "Agregar multa", "Se agregó la multa de forma correcta.");
        }*/
    }

    public void changeOwner() {
        /*if (selectedLoan.getLoanStatus() != LoanStatus.APPROVED) {
            selectedLoan = null;
            userId = "";
            showMessage(FacesMessage.SEVERITY_WARN, "No se puede modificar propietario", "Solo puedes cambiar de propietario a préstamos en estatus Aprobados");
            return;
        }
        LoanByUser old = new LoanByUser();
        old = loanCtrl.getLoanByUserByIdLoan(selectedLoan);

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

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

        loanByUser.setId(idRelation);
        loanByUser.setComments(old.getComments());
        loanByUser.setCreatedBy(old.getCreatedBy());
        loanByUser.setLoanByUserStatus(old.getLoanByUserStatus());
        loanByUser.setLoan(selectedLoan);
        loanByUser.setOrderInList(old.getOrderInList());
        loanByUser.setOwnerLoan(OwnerLoan.CURRENT_OWNER);
        loanByUser.setUser(new User(userId));
        if (loanCtrl.deleteLoanByUser(old)) {
            loanCtrl.saveLoanByUser(loanByUser);
            selectedLoan = null;
            userId = "";
            loan.clear();
            loan = fillDatatableLoan();
            showMessage(FacesMessage.SEVERITY_INFO, "Cambio de propietario", "Se reasignó el préstamo de forma correcta.");
        } else {
            selectedLoan = null;
            showMessage(FacesMessage.SEVERITY_ERROR, "Cambio de propietario", "Ocurrió un error al intentar hacer el cambio de propietario.");
        }*/
    }

    /**
     *
     */
    private void initStartAndEndDates() {
        try {
            Calendar starDateCalendar = Calendar.getInstance();

            starDateCalendar.setTime(DateWrapper.getTodayMXTime());
            starDateCalendar.add(Calendar.MONTH, -1);

            setStarDate(starDateCalendar.getTime());
            setEndDate(DateWrapper.getTodayMXTime());
        } catch (Exception e) {

        }
    }

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

    @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() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

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

    /**
     *
     * @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<HistoryLoanView> getLoan() {
        return loan;
    }

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

    public HistoryLoanView getSelectedLoan() {
        return selectedLoan;
    }

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

    public String getComments() {
        return comments;
    }

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

    public GenericController getGenericCtrl() {
        return genericCtrl;
    }

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

    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 BigDecimal getPayment() {
        return payment;
    }

    public void setPayment(BigDecimal payment) {
        this.payment = payment;
    }

    public BigDecimal getFee() {
        return fee;
    }

    public void setFee(BigDecimal fee) {
        this.fee = fee;
    }

    public LoanTypeController getLoanTypeCtrl() {
        return loanTypeCtrl;
    }

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

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

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

    public String getLoanTypeId() {
        return loanTypeId;
    }

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

    public String getRouteId() {
        return routeId;
    }

    public void setRouteId(String routeId) {
        this.routeId = routeId;
    }

    public RouteController getRouteCtrl() {
        return routeCtrl;
    }

    public void setRouteCtrl(RouteController routeCtrl) {
        this.routeCtrl = routeCtrl;
    }

    public List<RouteCtlg> getRoute() {
        return route;
    }

    public void setRoute(List<RouteCtlg> route) {
        this.route = route;
    }

    public Date getStarDate() {
        return starDate;
    }

    public void setStarDate(Date starDate) {
        this.starDate = starDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    private LoanController loanCtrl;
    private LoanTypeController loanTypeCtrl;
    private GenericController genericCtrl;
    private RouteController routeCtrl;

    private List<HistoryLoanView> loan;
    private List<User> users;
    private List<LoanType> loanType;
    private List<RouteCtlg> route;
    private HistoryLoanView selectedLoan;
    private String comments;
    private String userId;
    private BigDecimal payment;
    private BigDecimal fee;
    private String loanTypeId;
    private String routeId;

    private Date starDate;
    private Date endDate;

    @PostConstruct
    public void init() {
        loadBundlePropertyFile();
        
        loanCtrl = new LoanController();
        genericCtrl = new GenericController();
        loanTypeCtrl = new LoanTypeController();
        routeCtrl = new RouteController();
        initStartAndEndDates();
        users = genericCtrl.getAllUsersByOffice(getLoggedUser().getOffice().getId());
        loanType = loanTypeCtrl.fillLoanTypeDatatable(getLoggedUser().getOffice().getId());
        route = routeCtrl.fillRoutesDatatable(getLoggedUser().getOffice().getId());

        setLoan(fillDatatableLoan());
    }

}
