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

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.admin.TransferController;
import com.arrebol.taxiservicios.controller.lazy.services.TransferMutualService;
import com.arrebol.taxiservicios.controller.mutual.TransferMutualController;
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.mutual.TransferMutual;
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 Oscar Vargas
 */
@Named("transferMutualBean")
@ViewScoped
public class TransferMutualBean 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.PENDING);
            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 TransferMutual());

                setTransferMutualEnebled(getController().findAllTransfer());
            } 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().getAmountToTransfer())
                        + " y fecha " + getSelectedTransferView().getCreatedOn();

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

                setSelectedTransferView(null);
                setCommentsBitacora("");

                setTransferMutualEnebled(getController().findAllTransfer());
            }
        } 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) {
        getTransferMutualEnebled().forEach((transfer) -> {
            if (transfer.getId().equals(id)) {
                setSelectedTransferView(transfer);
            }
        });
    }

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

                @Override
                public List<TransferMutual> 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(TransferMutual row) {
                    return row.getId();
                }

                @Override
                public TransferMutual 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);
        }
    }

    public void autorizarPending() {
        logger.info("noPrintSale");

        try {
            boolean success = getController().autorizar(getSelectedTransferView().getId(), getLoggedUser());

            if (success) {
                setSelectedTransferView(null);

                showMessage(FacesMessage.SEVERITY_INFO,
                        "Autorizar",
                        "Se autorizó correctamente");
                transferMutualPending = getController().findAllTransferPendingByUser(getLoggedUser());
            } else {
                logger.error("Sale " + getSelectedTransferView() + "was not changed to no print");
                showMessage(FacesMessage.SEVERITY_ERROR,
                        "Autorizar",
                        "No se pudo autorizar");
            }

        } catch (Exception e) {
            logger.error("autorizar: " + e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("sale.noprint.title"),
                    getBundlePropertyFile().getString("sale.noprint.exception.desc"));
        }

    }

    @PostConstruct
    public void init() {
        logger.info("init");
        try {
            loadBundlePropertyFile();
            loadingLazyDataTable();
            setController(new TransferMutualController());
            newTransfer = new TransferMutual();
            setUsers(transferService.findAllSystemUser());
            transferMutualEnebled = getController().findAllTransfer();
            transferMutualPending = getController().findAllTransferPendingByUser(getLoggedUser());
            Double amountTransfer = transferService.findTotals(query_total_transfer, getLoggedUser().getId());
            Double amountSalesTransfer = transferService.findTotals(query_total_sales, getLoggedUser().getId()) - amountTransfer;
            getNewTransfer().setAmountToTransfer(amountSalesTransfer);
        } catch (Exception e) {
            logger.error(e);
        }
    }

    private TransferMutual newTransfer;
    private BigDecimal amount;
    private String commentsBitacora;
    private String idUser;
    private List<User> users;
    private LazyDataModel<TransferMutual> transferViews;
    private List<TransferMutual> transferMutualPending;
    private List<TransferMutual> transferMutualEnebled;
    private TransferMutual selectedTransferView;
    private TransferMutualController controller;

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

    public TransferMutualController getController() {
        return controller;
    }

    public void setController(TransferMutualController controller) {
        this.controller = controller;
    }

    public List<TransferMutual> getTransferMutualPending() {
        return transferMutualPending;
    }

    public void setTransferMutualPending(List<TransferMutual> transferMutualPending) {
        this.transferMutualPending = transferMutualPending;
    }

    public List<TransferMutual> getTransferMutualEnebled() {
        return transferMutualEnebled;
    }

    public void setTransferMutualEnebled(List<TransferMutual> transferMutualEnebled) {
        this.transferMutualEnebled = transferMutualEnebled;
    }

    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 TransferMutual getNewTransfer() {
        return newTransfer;
    }

    public void setNewTransfer(TransferMutual 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<TransferMutual> getTransferViews() {
        return transferViews;
    }

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

    public TransferMutual getSelectedTransferView() {
        return selectedTransferView;
    }

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

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

    private final String sub_query_to_find_previously_closing_day = "(SELECT DATE(cd.created_on) FROM CLOSING_DAY cd WHERE DATE(cd.created_on) <= CURDATE() AND cd.user_id = :userID AND cd.active_status = 'ENEBLED' order by cd.created_on DESC LIMIT 1)";
    private final String query_total_sales = "SELECT IF(ISNULL(SUM(accident)),0 , SUM(accident)) AS total_sales FROM SALE WHERE DATE(created_on) > " + sub_query_to_find_previously_closing_day + " AND created_by = :userID AND transfer = 'DISABLED'";
    private final String query_total_transfer = "SELECT IF(ISNULL(SUM(amount_to_transfer)), 0, SUM(amount_to_transfer)) FROM TRANSFER_MUTUAL WHERE DATE(created_on) > " + sub_query_to_find_previously_closing_day + " AND active_status = 'ENEBLED' AND action_status = 'APPROVED' "
            + "AND id_user_transmitter = :userID";

}
