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

import com.arrebol.taxiservicios.beans.Datatable;
import com.arrebol.taxiservicios.beans.TaxiGenericBean;
import com.arrebol.taxiservicios.controller.admin.BitacoraService;
import com.arrebol.taxiservicios.controller.admin.ClosingDayService;
import com.arrebol.taxiservicios.controller.lazy.services.TransferService;
import com.arrebol.taxiservicios.model.admin.Transfer;
import com.arrebol.taxiservicios.model.core.User;
import com.arrebol.taxiservicios.model.enums.ActionStatus;
import com.arrebol.taxiservicios.model.enums.BasicType;
import com.arrebol.taxiservicios.model.view.admin.TransferView;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.primefaces.event.ReorderEvent;
import org.primefaces.event.RowEditEvent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;

/**
 *
 * @author Carlos Janitzio Zavala Lopez <janitzio.zavala@arrebol.com.mx>
 */
@Named("transferBean")
@ViewScoped
public class TransferBean extends TaxiGenericBean implements Serializable, Datatable {

    @Override
    public void addRow() {
        logger.info("addRow");
        
        if (closingDayService.existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Error",
                        "No se puede hacer ninguna acción si existe un corte del día");
                return;
            }
        
        try {
            getNewTransfer().setId(UUID.randomUUID().toString());
            getNewTransfer().setActiveStatus(BasicType.ENEBLED);
            getNewTransfer().setActionStatus(ActionStatus.APPROVED);
            getNewTransfer().setUserTransmitter(new User(getLoggedUser().getId(), ""));
            getNewTransfer().setUserReceiver(new User(idUser, ""));
            getNewTransfer().setCreatedOn(new Date());
            getNewTransfer().setCreatedBy(new User(getLoggedUser().getId(), ""));

            if (transferService.saveTransfer(getNewTransfer())) {
                showMessage(FacesMessage.SEVERITY_INFO,
                        "Transferencia",
                        "Se agregó correctamente");
                setNewTransfer(new Transfer());
            } else {
                showMessage(FacesMessage.SEVERITY_ERROR,
                        "Transferencia",
                        "Ocurrió un error al intentar guardar.");
            }
        } catch (Exception e) {
            logger.error("addRow", e);
            showMessage(FacesMessage.SEVERITY_ERROR,
                    "Transferencia",
                    "Ocurrió un error al intentar guardar.");
        }
    }

    @Override
    public void deleteRow() {
        try {
            if (closingDayService.existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Error",
                        "No se puede hacer ninguna acción si existe un corte del día");
                return;
            }

            if (transferService.updateTransferTStatus(getSelectedTransferView().getId(), BasicType.DISABLED, getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_INFO,
                        "Eliminación de transferencia",
                        "Se eliminó correctamente");

                if (null == getCommentsBitacora() || getCommentsBitacora().trim().equals("")) {
                    setCommentsBitacora("El usuario " + getLoggedUser().getUserName() + " no agrego comentarios a la hora de borrar este gasto administrativo");
                }

                String actionBitacora = "Eliminar transferencia";
                String descBitacora = "Se eliminó la transferencia con monto "
                        + currencyFormatNumber(getSelectedTransferView().getAmount())
                        + " y fecha " + getSelectedTransferView().getStrTransferDate();

                bitacoraService.saveNewRecordInBitacora(createNewRecordInBitacora(UUID.randomUUID().toString(), actionBitacora, getCommentsBitacora(), descBitacora),
                        getLoggedUser().getLocation().getId());

                setSelectedTransferView(null);
                setCommentsBitacora("");
            }
        } catch (Exception e) {
            showMessage(FacesMessage.SEVERITY_WARN,
                    "Error",
                    "No se pudo borrar la transfrencia");
        }

    }

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

    public void addSelectedTransferViewDetails(String id) {
        getTransferViews().forEach((transfer) -> {
            if (transfer.getId().equals(id)) {
                setSelectedTransferView(transfer);
            }
        });
    }

    private void loadingLazyDataTable() {
        try {
            setTransferViews(new LazyDataModel<TransferView>() {
                private List<TransferView> lazyEntityList;

                @Override
                public List<TransferView> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filterBy) {
                    try {
                        Long total = transferService.countPaginator(filterBy);

                        setRowCount(total.intValue());

                        lazyEntityList = transferService.lazyEntityListPaginator(first, pageSize, sortField, sortOrder, filterBy);

                        return lazyEntityList;
                    } catch (Exception e) {
                        logger.error("lazy Entity List", e);
                        setRowCount(0);
                        return new ArrayList<>();
                    }
                }

                @Override
                public String getRowKey(TransferView row) {
                    return row.getId();
                }

                @Override
                public TransferView getRowData(String rowKey) {
                    return lazyEntityList
                            .stream()
                            .filter(row -> rowKey.equals(row.getId()))
                            .findFirst()
                            .orElse(null);
                }
            }
            );
        } catch (Exception e) {
            logger.error("Lazy Data Model Transfer View ", e);
        }
    }

    @PostConstruct
    public void init() {
        logger.info("init");
        try {
            loadBundlePropertyFile();
            loadingLazyDataTable();
            newTransfer = new Transfer();
            setUsers(transferService.findAllSystemUser());
        } catch (Exception e) {
            logger.error(e);
        }
    }

    private Transfer newTransfer;
    private BigDecimal amount;
    private String commentsBitacora;
    private String idUser;
    private List<User> users;
    private LazyDataModel<TransferView> transferViews;
    private TransferView selectedTransferView;

    @Inject
    private TransferService transferService;
    @Inject
    private BitacoraService bitacoraService;
    @Inject
    private ClosingDayService closingDayService;

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

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

    public String getIdUser() {
        return idUser;
    }

    public void setIdUser(String idUser) {
        this.idUser = idUser;
    }

    public Transfer getNewTransfer() {
        return newTransfer;
    }

    public void setNewTransfer(Transfer newTransfer) {
        this.newTransfer = newTransfer;
    }

    public BigDecimal getAmount() {
        return amount;
    }

    public void setAmount(BigDecimal amount) {
        this.amount = amount;
    }

    public String getCommentsBitacora() {
        return commentsBitacora;
    }

    public void setCommentsBitacora(String commentsBitacora) {
        this.commentsBitacora = commentsBitacora;
    }

    public LazyDataModel<TransferView> getTransferViews() {
        return transferViews;
    }

    public void setTransferViews(LazyDataModel<TransferView> transferViews) {
        this.transferViews = transferViews;
    }

    public TransferView getSelectedTransferView() {
        return selectedTransferView;
    }

    public void setSelectedTransferView(TransferView selectedTransferView) {
        this.selectedTransferView = selectedTransferView;
    }

    private static final long serialVersionUID = 3399229987467371585L;
    final Logger logger = LogManager.getLogger(getClass());
}
