package it.integry.integrywmsnative.gest.accettazione_ordini_picking;

import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Bundle;
import android.text.SpannableString;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ObservableArrayList;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.annimon.stream.Stream;
import com.tfb.fbtoast.FBToast;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import javax.inject.Inject;

import it.integry.barcode_base_android_library.model.BarcodeScanDTO;
import it.integry.integrywmsnative.MainApplication;
import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.CommonConst;
import it.integry.integrywmsnative.core.barcode_reader.BarcodeCallbackDTO;
import it.integry.integrywmsnative.core.barcode_reader.BarcodeManager;
import it.integry.integrywmsnative.core.data_cache.DataCache;
import it.integry.integrywmsnative.core.di.BindableBoolean;
import it.integry.integrywmsnative.core.expansion.BaseActivity;
import it.integry.integrywmsnative.core.expansion.OnGeneralChangedCallback;
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.expansion.RunnableArgss;
import it.integry.integrywmsnative.core.model.MtbAart;
import it.integry.integrywmsnative.core.model.MtbColr;
import it.integry.integrywmsnative.core.model.MtbColt;
import it.integry.integrywmsnative.core.model.MtbTCol;
import it.integry.integrywmsnative.core.model.dto.AlreadyRegisteredUDCDTO;
import it.integry.integrywmsnative.core.model.secondary.GestioneEnum;
import it.integry.integrywmsnative.core.report.ReportManager;
import it.integry.integrywmsnative.core.rest.model.VersamentoAutomaticoULResponseDTO;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import it.integry.integrywmsnative.core.utility.UtilityBigDecimal;
import it.integry.integrywmsnative.core.utility.UtilityDate;
import it.integry.integrywmsnative.core.utility.UtilityExceptions;
import it.integry.integrywmsnative.core.utility.UtilityResources;
import it.integry.integrywmsnative.core.utility.UtilityString;
import it.integry.integrywmsnative.core.utility.UtilityToast;
import it.integry.integrywmsnative.databinding.ActivityAccettazioneOrdineInevasoBinding;
import it.integry.integrywmsnative.gest.accettazione_ordini_elenco.dto.OrdineAccettazioneInevasoDTO;
import it.integry.integrywmsnative.gest.accettazione_ordini_elenco.dto.SitArtOrdDTO;
import it.integry.integrywmsnative.gest.accettazione_ordini_picking.dto.AccettazioneOrdineInevasoOrderBy;
import it.integry.integrywmsnative.gest.accettazione_ordini_picking.dto.PickingObjectDTO;
import it.integry.integrywmsnative.gest.accettazione_ordini_picking.filters.AccettazionePickingFiltroOrdineViewModel;
import it.integry.integrywmsnative.gest.accettazione_ordini_picking.filters.FilterCodArtLayoutView;
import it.integry.integrywmsnative.gest.accettazione_ordini_picking.filters.FilterDescrLayoutView;
import it.integry.integrywmsnative.gest.accettazione_ordini_picking.filters.FilterPosizioneLayoutView;
import it.integry.integrywmsnative.gest.accettazione_ordini_picking.ui.AccettazioneOrdiniPickingListAdapter;
import it.integry.integrywmsnative.gest.accettazione_ordini_picking.ui.AccettazioneOrdiniPickingListModel;
import it.integry.integrywmsnative.gest.lista_bancali.ListaBancaliActivity;
import it.integry.integrywmsnative.gest.spedizione.exceptions.InvalidPesoKGException;
import it.integry.integrywmsnative.gest.spedizione.model.PickedQuantityDTO;
import it.integry.integrywmsnative.ui.filter_chips.FilterChipDTO;
import it.integry.integrywmsnative.ui.filter_chips.FilterChipView;
import it.integry.integrywmsnative.view.bottom_sheet__lu_content.BottomSheetFragmentLUContentView;
import it.integry.integrywmsnative.view.bottom_sheet__lu_content.BottomSheetFragmentLUContentViewModel;
import it.integry.integrywmsnative.view.dialogs.ask_should_versamento_automatico_ul.DialogAskShouldVersamentoAutomaticoULView;
import it.integry.integrywmsnative.view.dialogs.base.DialogSimpleMessageView;
import it.integry.integrywmsnative.view.dialogs.info_aggiuntive_lu.DialogInfoAggiuntiveLUView;
import it.integry.integrywmsnative.view.dialogs.input_quantity_v2.DialogInputQuantityV2DTO;
import it.integry.integrywmsnative.view.dialogs.input_quantity_v2.DialogInputQuantityV2View;
import it.integry.integrywmsnative.view.dialogs.versamento_automatico_ul_done.DialogVersamentoAutomaticoULDoneView;

public class AccettazioneOrdiniPickingActivity extends BaseActivity implements AccettazioneOrdiniPickingViewModel.Listener, BottomSheetFragmentLUContentViewModel.Listener, BottomSheetFragmentLUContentView.Listener {

    private ActivityAccettazioneOrdineInevasoBinding mBindings;

    @Inject
    AccettazioneOrdiniPickingViewModel mViewModel;

    @Inject
    DialogInputQuantityV2View mDialogInputQuantityV2View;

    private final AccettazionePickingFiltroOrdineViewModel mAppliedFilterViewModel = new AccettazionePickingFiltroOrdineViewModel();

    private BottomSheetFragmentLUContentViewModel mBottomSheetFragmentLUContentViewModel;

    private final ObservableArrayList<AccettazioneOrdiniPickingListModel> mAccettazioneMutableData = new ObservableArrayList<>();


    public BindableBoolean noItemsToPick = new BindableBoolean(false);
    public BindableBoolean noLUPresent = new BindableBoolean(true);
    public BindableBoolean bottomSheetEnabled = new BindableBoolean(false);

    private int barcodeScannerIstanceID = -1;

    private List<OrdineAccettazioneInevasoDTO> mOrders;
    private List<SitArtOrdDTO> mSitArts;

    private boolean mShouldCloseActivity;
    private AccettazioneOrdineInevasoOrderBy.Enum mCurrentOrderBy;

    private final int PICK_UL_REQUEST = 1;

    private boolean mShowSecondaryUntMis = true;

    private PopupMenu fabPopupMenu;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mOrders = DataCache.retrieveItem(getIntent().getStringExtra("keyOrders"));
        mSitArts = DataCache.retrieveItem(getIntent().getStringExtra("keySitArts"));


        mBindings = DataBindingUtil.setContentView(this, R.layout.activity_accettazione_ordine_inevaso);
        mBindings.setLifecycleOwner(this);
        mBindings.setView(this);

        MainApplication.appComponent
                .accettazionePickingComponent()
                .create()
                .inject(this);

        setSupportActionBar(mBindings.toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        mBottomSheetFragmentLUContentViewModel = mBindings.bottomSheetLuContent.getViewModelInstance();
        mBindings.bottomSheetLuContent.setListener(this);
        mBottomSheetFragmentLUContentViewModel.setListener(this);

        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        mShowSecondaryUntMis = sharedPreferences.getBoolean("picking_ingresso_enable_sec_unt_mis", true);

        this.initVars();
        this.initBarcodeReader();
        this.initRecyclerView();
        this.initFilters();
        this.initFab();

        boolean useQtaOrd = SettingsManager.iDB().isFlagAccettazioneUseQtaOrd();

        mViewModel.setListeners(this);
        mViewModel.init(
                mOrders,
                mSitArts,
                useQtaOrd);
    }

    private void initFab() {
        fabPopupMenu = new PopupMenu(this, this.mBindings.accettazioneOrdineInevasoFab,
                (Gravity.END | Gravity.BOTTOM),
                androidx.appcompat.R.attr.popupMenuStyle,
                com.google.android.material.R.style.Widget_Material3_PopupMenu_ContextMenu);

        fabPopupMenu.setForceShowIcon(true);
        fabPopupMenu.getMenuInflater().inflate(R.menu.accettazione_ordine_inevaso_fab_menu, fabPopupMenu.getMenu());

        fabPopupMenu.setOnMenuItemClickListener(item -> {
            int itemId = item.getItemId();

            if (itemId == R.id.show_created_ul) {
                showCreatedUL();
            } else if (itemId == R.id.create_ul) {
                createNewLU();
            }

            return false;
        });
    }

    private void initFilters() {

        var onPredicateChanged = new OnGeneralChangedCallback() {
            @Override
            public void run() {
                refreshList();
            }
        };

        mAppliedFilterViewModel.getCurrentCodArtPredicate().addOnPropertyChangedCallback(onPredicateChanged);
        mAppliedFilterViewModel.getCurrentDescrPredicate().addOnPropertyChangedCallback(onPredicateChanged);
        mAppliedFilterViewModel.getCurrentPosPredicate().addOnPropertyChangedCallback(onPredicateChanged);

        List<FilterChipDTO> filterList = Stream.of(AccettazioneOrdiniPickingBindings.AVAILABLE_FILTERS.entrySet())
                .map(Map.Entry::getValue)
                .sortBy(FilterChipDTO::getPosizione)
                .toList();

        for (FilterChipDTO filterChipDTO : filterList) {

            FilterChipView filterChipView = new FilterChipView(
                    this,
                    filterChipDTO.getFilterChipText(),
                    v -> initBottomSheetDialogFilter(filterChipDTO));

            switch (filterChipDTO.getID()) {
                case AccettazioneOrdiniPickingBindings.COD_ART_FILTER_ID -> {
                    mAppliedFilterViewModel.getCurrentCodArtPredicate().addOnPropertyChangedCallback(new OnGeneralChangedCallback() {
                        @Override
                        public void run() {
                            if (mAppliedFilterViewModel.getCurrentCodArtPredicate().get() == null) {
                                mViewModel.resetMatchedRows();
                                filterChipView.disableCloseIcon();

                                mBindings.filterChipsGroup.removeView(filterChipView);
                                mBindings.filterChipsGroup.addView(filterChipView);
                                mBindings.filterChips.smoothScrollTo(0, 0);
                            } else {
                                filterChipView.enableCloseIcon();

                                mBindings.filterChipsGroup.removeView(filterChipView);
                                mBindings.filterChipsGroup.addView(filterChipView, 0);
                                mBindings.filterChips.smoothScrollTo(0, 0);
                            }
                        }
                    });
                    filterChipView.setOnResetClicked(() -> mAppliedFilterViewModel.getCurrentCodArtPredicate().set(null));
                }
                case AccettazioneOrdiniPickingBindings.DESCR_FILTER_ID -> {
                    mAppliedFilterViewModel.getCurrentDescrPredicate().addOnPropertyChangedCallback(new OnGeneralChangedCallback() {
                        @Override
                        public void run() {
                            if (mAppliedFilterViewModel.getCurrentDescrPredicate().get() == null) {
                                mViewModel.resetMatchedRows();
                                filterChipView.disableCloseIcon();

                                mBindings.filterChipsGroup.removeView(filterChipView);
                                mBindings.filterChipsGroup.addView(filterChipView);
                                mBindings.filterChips.smoothScrollTo(0, 0);
                            } else {
                                filterChipView.enableCloseIcon();

                                mBindings.filterChipsGroup.removeView(filterChipView);
                                mBindings.filterChipsGroup.addView(filterChipView, 0);
                                mBindings.filterChips.smoothScrollTo(0, 0);
                            }
                        }
                    });
                    filterChipView.setOnResetClicked(() -> mAppliedFilterViewModel.getCurrentDescrPredicate().set(null));
                }
                case AccettazioneOrdiniPickingBindings.POS_FILTER_ID -> {
                    mAppliedFilterViewModel.getCurrentPosPredicate().addOnPropertyChangedCallback(new OnGeneralChangedCallback() {
                        @Override
                        public void run() {
                            if (mAppliedFilterViewModel.getCurrentPosPredicate().get() == null) {
                                mViewModel.resetMatchedRows();
                                filterChipView.disableCloseIcon();

                                mBindings.filterChipsGroup.removeView(filterChipView);
                                mBindings.filterChipsGroup.addView(filterChipView);
                                mBindings.filterChips.smoothScrollTo(0, 0);
                            } else {
                                filterChipView.enableCloseIcon();

                                mBindings.filterChipsGroup.removeView(filterChipView);
                                mBindings.filterChipsGroup.addView(filterChipView, 0);
                                mBindings.filterChips.smoothScrollTo(0, 0);
                            }
                        }
                    });
                    filterChipView.setOnResetClicked(() -> mAppliedFilterViewModel.getCurrentPosPredicate().set(null));
                }
            }

            this.mBindings.filterChipsGroup.addView(filterChipView);
        }
    }


    private void initBottomSheetDialogFilter(FilterChipDTO filterChipDTO) {

        filterChipDTO
                .getFilterLayoutView()
                .setFilterName(filterChipDTO.getFilterChipText())
                .setContext(this);

        var filterLayoutView = filterChipDTO
                .getFilterLayoutView();

        switch (filterChipDTO.getID()) {
            case AccettazioneOrdiniPickingBindings.COD_ART_FILTER_ID ->
                    ((FilterCodArtLayoutView) filterLayoutView)
                            .setAll(mAppliedFilterViewModel.getAllCodArts())
                            .setAvailable(mAppliedFilterViewModel.getAvailableCodArts())
                            .setOnFilterApplied(mAppliedFilterViewModel::setCodArtFilter)
                            .setPreselected(Stream.of(Objects.requireNonNull(mViewModel.getPickingList().getValue()))
                                    .filter(mAppliedFilterViewModel.getCurrentCodArtPredicate().get() == null ?
                                            x -> false :
                                            mAppliedFilterViewModel.getCurrentCodArtPredicate().get())
                                    .map(x -> x.getSitArtOrdDTO().getCodMart())
                                    .toList());
            case AccettazioneOrdiniPickingBindings.DESCR_FILTER_ID ->
                    ((FilterDescrLayoutView) filterLayoutView)
                            .setAll(mAppliedFilterViewModel.getAllDescrs())
                            .setAvailable(mAppliedFilterViewModel.getAvailableDescrs())
                            .setOnFilterApplied(mAppliedFilterViewModel::setDescrFilter)
                            .setPreselected(Stream.of(Objects.requireNonNull(mViewModel.getPickingList().getValue()))
                                    .filter(mAppliedFilterViewModel.getCurrentDescrPredicate().get() == null ?
                                            x -> false :
                                            mAppliedFilterViewModel.getCurrentDescrPredicate().get())
                                    .map(x -> x.getSitArtOrdDTO().getDescrizioneEstesaArt())
                                    .toList());
            case AccettazioneOrdiniPickingBindings.POS_FILTER_ID ->
                    ((FilterPosizioneLayoutView) filterLayoutView)
                            .setAll(mAppliedFilterViewModel.getAllPos())
                            .setAvailable(mAppliedFilterViewModel.getAvailablePos())
                            .setOnFilterApplied(mAppliedFilterViewModel::setPosFilter)
                            .setPreselected(Stream.of(Objects.requireNonNull(mViewModel.getPickingList().getValue()))
                                    .filter(mAppliedFilterViewModel.getCurrentPosPredicate().get() == null ?
                                            x -> false :
                                            mAppliedFilterViewModel.getCurrentPosPredicate().get())
                                    .map(x -> x.getMtbAart().getPosizione())
                                    .toList());
        }

        if (!filterLayoutView.isAdded())
            filterLayoutView.show(getSupportFragmentManager(), "TAG");
    }

    @Override
    public boolean onSupportNavigateUp() {
        onBackPressed();
        return true;
    }

    @Override
    public void onBackPressed() {
        if (this.mBindings.bottomSheetLuContent.isExpanded()) {
            this.mBindings.bottomSheetLuContent.collapse();
        } else if (!noLUPresent.get()) {
            this.mShouldCloseActivity = true;
            BarcodeManager.removeCallback(barcodeScannerIstanceID);
            this.mViewModel.closeLU();
        } else {
            BarcodeManager.removeCallback(barcodeScannerIstanceID);
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_accettazione_ordine_inevaso, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        if (item.getItemId() == R.id.action_filter) {
            showOrderByDialog();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void initVars() {
        this.noLUPresent.addOnPropertyChangedCallback(() -> {
            this.bottomSheetEnabled.set(!this.noLUPresent.get());
        });

        mCurrentOrderBy = AccettazioneOrdineInevasoOrderBy.Enum.fromInt(SettingsManager.i().getUserSession().getDefaultOrdinamentoPickingAccettazione());
    }

    private void initBarcodeReader() {
        barcodeScannerIstanceID = BarcodeManager.addCallback(new BarcodeCallbackDTO()
                .setOnScanSuccessful(onScanSuccessful)
                .setOnScanFailed(ex -> UtilityExceptions.defaultException(this, ex, false)));
    }

    private void initRecyclerView() {
        AccettazioneOrdiniPickingListAdapter accettazioneOrdiniPickingListAdapter = new AccettazioneOrdiniPickingListAdapter(this, mAccettazioneMutableData, mShowSecondaryUntMis);
        this.mBindings.accettazionePickingList.setAdapter(accettazioneOrdiniPickingListAdapter);
        this.mBindings.accettazionePickingList.setLayoutManager(new LinearLayoutManager(this));

        this.mViewModel.getPickingList().observe(this, updatedData -> {
            mAppliedFilterViewModel.init(updatedData);

            refreshList();
        });

        accettazioneOrdiniPickingListAdapter.setOnItemClicked(clickedItem -> {
            this.mViewModel.dispatchOrdineRow(clickedItem);
        });
    }

    private void refreshList() {

        runOnUiThread(() -> {
            List<PickingObjectDTO> tmpList;

            if (mAppliedFilterViewModel != null) {
                mAppliedFilterViewModel.applyAllTests();
                tmpList = mAppliedFilterViewModel.getMutableFilteredOrderList().getValue();
            } else {
                tmpList = mViewModel.getPickingList().getValue();
            }

            var list = convertDataModelToListModel(tmpList);

            this.mAccettazioneMutableData.clear();
            this.mAccettazioneMutableData.addAll(list);
            this.noItemsToPick.set(!isThereAnyItemToPick(tmpList));

        });
    }

    private List<AccettazioneOrdiniPickingListModel> convertDataModelToListModel(List<PickingObjectDTO> dataList) {
        List<PickingObjectDTO> tmpList = Stream.of(dataList)
                .filter(x -> !x.isHidden() && UtilityBigDecimal.greaterThan(x.getSitArtOrdDTO().getQtaDaEvadere(), BigDecimal.ZERO))
                .toList();

        return switch (mCurrentOrderBy) {
            case COD_ART_FOR -> convertDataModelToListModel__CodArtForn(tmpList);
            case DESCR_ART -> convertDataModelToListModel__DescrArt(tmpList);
            case RAG_SOC_COM -> convertDataModelToListModel__RagSocCom(tmpList);
        };
    }

    private List<AccettazioneOrdiniPickingListModel> convertDataModelToListModel__CodArtForn(List<PickingObjectDTO> dataList) {
        ArrayList<AccettazioneOrdiniPickingListModel> list = new ArrayList<>();
        Stream.of(dataList)
                .sortBy(x -> UtilityString.isNull(x.getSitArtOrdDTO().getCodArtFor(), x.getSitArtOrdDTO().getCodMart()) +
                        (UtilityString.isNullOrEmpty(x.getMtbAart().getDescrizioneEstesa()) ? "" : " - " + x.getMtbAart().getDescrizioneEstesa()))
                .forEach(x -> {
                    AccettazioneOrdiniPickingListModel accettazioneOrdiniPickingListModel = new AccettazioneOrdiniPickingListModel();
                    accettazioneOrdiniPickingListModel.setActive(true);

                    accettazioneOrdiniPickingListModel.setGroupTitle(UtilityString.isNull(x.getSitArtOrdDTO().getCodArtFor(), x.getSitArtOrdDTO().getCodMart()) +
                            (UtilityString.isNullOrEmpty(x.getMtbAart().getDescrizioneEstesa()) ? "" : " - " + x.getMtbAart().getDescrizioneEstesa()));

                    accettazioneOrdiniPickingListModel.setBadge1(UtilityString.isNull(x.getSitArtOrdDTO().getCodJcom(), CommonConst.Config.COMMESSA_MAG));
                    accettazioneOrdiniPickingListModel.setBadge2(String.valueOf(x.getSitArtOrdDTO().getNumOrd()));

                    accettazioneOrdiniPickingListModel.setSubDescrizione1("Consegna: " + UtilityDate.formatDate(x.getSitArtOrdDTO().getDataCons(), UtilityDate.COMMONS_DATE_FORMATS.DMY_SLASH));

                    accettazioneOrdiniPickingListModel.setDescrizione(x.getSitArtOrdDTO().getDescrizioneCommessa());
                    if (x.getMtbAart() != null)
                        accettazioneOrdiniPickingListModel.setPosizione(x.getMtbAart().getPosizione());

                    //Calc Num CNF
                    BigDecimal numCnfEvasa = BigDecimal.ZERO;

                    if (x.getWithdrawMtbColrs().size() > 0) {
                        numCnfEvasa = Stream.of(x.getWithdrawMtbColrs())
                                .map(MtbColr::getNumCnf)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                    }

                    //Calc qta col
                    BigDecimal qtaEvasa = BigDecimal.ZERO;

                    if (x.getWithdrawMtbColrs().size() > 0) {
                        qtaEvasa = Stream.of(x.getWithdrawMtbColrs())
                                .map(MtbColr::getQtaCol)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                    }


                    if (SettingsManager.iDB().isFlagForceAllToColli() || (x.getMtbAart() == null || !x.getMtbAart().isFlagQtaCnfFissaBoolean())) {
                        accettazioneOrdiniPickingListModel.setQtaEvasa(numCnfEvasa);
                        accettazioneOrdiniPickingListModel.setQtaTot(x.getSitArtOrdDTO().getNumCnfDaEvadere());
                        accettazioneOrdiniPickingListModel.setUntMis(UtilityResources.getString(R.string.unt_mis_col));

                        accettazioneOrdiniPickingListModel.setSecQtaEvasa(qtaEvasa);
                        accettazioneOrdiniPickingListModel.setSecQtaTot(x.getSitArtOrdDTO().getQtaDaEvadere());
                        if (x.getMtbAart() != null)
                            accettazioneOrdiniPickingListModel.setSecUntMis(x.getMtbAart().getUntMis());
                    } else {
                        accettazioneOrdiniPickingListModel.setQtaEvasa(qtaEvasa);
                        accettazioneOrdiniPickingListModel.setQtaTot(x.getSitArtOrdDTO().getQtaDaEvadere());
                        if (x.getMtbAart() != null)
                            accettazioneOrdiniPickingListModel.setUntMis(x.getMtbAart().getUntMis());

                        accettazioneOrdiniPickingListModel.setSecQtaEvasa(numCnfEvasa);
                        accettazioneOrdiniPickingListModel.setSecQtaTot(x.getSitArtOrdDTO().getNumCnfDaEvadere());
                        accettazioneOrdiniPickingListModel.setSecUntMis(UtilityResources.getString(R.string.unt_mis_col));
                    }

                    accettazioneOrdiniPickingListModel.setOriginalModel(x);

                    list.add(accettazioneOrdiniPickingListModel);
                });

        return list;
    }

    private List<AccettazioneOrdiniPickingListModel> convertDataModelToListModel__DescrArt(List<PickingObjectDTO> dataList) {
        ArrayList<AccettazioneOrdiniPickingListModel> list = new ArrayList<>();
        Stream.of(dataList)
                .sortBy(x -> x.getMtbAart().getDescrizioneEstesa())
                .forEach(x -> {
                    AccettazioneOrdiniPickingListModel accettazioneOrdiniPickingListModel = new AccettazioneOrdiniPickingListModel();
                    accettazioneOrdiniPickingListModel.setActive(true);

                    accettazioneOrdiniPickingListModel.setGroupTitle(UtilityString.isNull(x.getSitArtOrdDTO().getCodArtFor(), x.getSitArtOrdDTO().getCodMart())
                            + (UtilityString.isNullOrEmpty(x.getMtbAart().getDescrizioneEstesa()) ? "" : " - " + x.getMtbAart().getDescrizioneEstesa()));

                    accettazioneOrdiniPickingListModel.setBadge1(UtilityString.isNull(x.getSitArtOrdDTO().getCodJcom(), CommonConst.Config.COMMESSA_MAG));
                    accettazioneOrdiniPickingListModel.setBadge2(String.valueOf(x.getSitArtOrdDTO().getNumOrd()));

                    accettazioneOrdiniPickingListModel.setDescrizione(x.getSitArtOrdDTO().getDescrizioneCommessa());
                    if (x.getMtbAart() != null)
                        accettazioneOrdiniPickingListModel.setPosizione(x.getMtbAart().getPosizione());

                    //Calc Num CNF
                    BigDecimal numCnfEvasa = BigDecimal.ZERO;

                    if (x.getWithdrawMtbColrs().size() > 0) {
                        numCnfEvasa = Stream.of(x.getWithdrawMtbColrs())
                                .map(MtbColr::getNumCnf)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                    }

                    //Calc qta col
                    BigDecimal qtaEvasa = BigDecimal.ZERO;

                    if (x.getWithdrawMtbColrs().size() > 0) {
                        qtaEvasa = Stream.of(x.getWithdrawMtbColrs())
                                .map(MtbColr::getQtaCol)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                    }


                    if (SettingsManager.iDB().isFlagForceAllToColli() || (x.getMtbAart() == null || !x.getMtbAart().isFlagQtaCnfFissaBoolean())) {
                        accettazioneOrdiniPickingListModel.setQtaEvasa(numCnfEvasa);
                        accettazioneOrdiniPickingListModel.setQtaTot(x.getSitArtOrdDTO().getNumCnfDaEvadere());
                        accettazioneOrdiniPickingListModel.setUntMis(UtilityResources.getString(R.string.unt_mis_col));

                        accettazioneOrdiniPickingListModel.setSecQtaEvasa(qtaEvasa);
                        accettazioneOrdiniPickingListModel.setSecQtaTot(x.getSitArtOrdDTO().getQtaDaEvadere());
                        if (x.getMtbAart() != null)
                            accettazioneOrdiniPickingListModel.setSecUntMis(x.getMtbAart().getUntMis());
                    } else {
                        accettazioneOrdiniPickingListModel.setQtaEvasa(qtaEvasa);
                        accettazioneOrdiniPickingListModel.setQtaTot(x.getSitArtOrdDTO().getQtaDaEvadere());
                        if (x.getMtbAart() != null)
                            accettazioneOrdiniPickingListModel.setUntMis(x.getMtbAart().getUntMis());

                        accettazioneOrdiniPickingListModel.setSecQtaEvasa(numCnfEvasa);
                        accettazioneOrdiniPickingListModel.setSecQtaTot(x.getSitArtOrdDTO().getNumCnfDaEvadere());
                        accettazioneOrdiniPickingListModel.setSecUntMis(UtilityResources.getString(R.string.unt_mis_col));
                    }

                    accettazioneOrdiniPickingListModel.setOriginalModel(x);

                    list.add(accettazioneOrdiniPickingListModel);
                });

        return list;
    }

    private List<AccettazioneOrdiniPickingListModel> convertDataModelToListModel__RagSocCom(List<PickingObjectDTO> dataList) {
        ArrayList<AccettazioneOrdiniPickingListModel> list = new ArrayList<>();

        Stream.of(dataList)
                .filter(x -> !UtilityString.isNullOrEmpty(x.getSitArtOrdDTO().getDescrizioneCommessa()) && !x.getSitArtOrdDTO().getCodJcom().equalsIgnoreCase(CommonConst.Config.COMMESSA_MAG))
                .sortBy(x -> x.getSitArtOrdDTO().getDescrizioneCommessa())
                .forEach(x -> {
                    AccettazioneOrdiniPickingListModel accettazioneOrdiniPickingListModel = new AccettazioneOrdiniPickingListModel();
                    accettazioneOrdiniPickingListModel.setActive(true);

                    accettazioneOrdiniPickingListModel.setGroupTitle(x.getSitArtOrdDTO().getCodJcom() + (!UtilityString.isNullOrEmpty(x.getSitArtOrdDTO().getDescrizioneCommessa()) ? " - " + x.getSitArtOrdDTO().getDescrizioneCommessa() : ""));

                    accettazioneOrdiniPickingListModel.setBadge1(UtilityString.isNull(x.getSitArtOrdDTO().getCodArtFor(), x.getSitArtOrdDTO().getCodMart()));
                    accettazioneOrdiniPickingListModel.setBadge2(String.valueOf(x.getSitArtOrdDTO().getNumOrd()));

                    //Calc Num CNF
                    BigDecimal numCnfEvasa = BigDecimal.ZERO;

                    if (x.getWithdrawMtbColrs().size() > 0) {
                        numCnfEvasa = Stream.of(x.getWithdrawMtbColrs())
                                .map(MtbColr::getNumCnf)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                    }

                    //Calc qta col
                    BigDecimal qtaEvasa = BigDecimal.ZERO;

                    if (x.getWithdrawMtbColrs().size() > 0) {
                        qtaEvasa = Stream.of(x.getWithdrawMtbColrs())
                                .map(MtbColr::getQtaCol)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                    }


                    if (SettingsManager.iDB().isFlagForceAllToColli() || (x.getMtbAart() == null || !x.getMtbAart().isFlagQtaCnfFissaBoolean())) {
                        accettazioneOrdiniPickingListModel.setQtaEvasa(numCnfEvasa);
                        accettazioneOrdiniPickingListModel.setQtaTot(x.getSitArtOrdDTO().getNumCnfDaEvadere());
                        accettazioneOrdiniPickingListModel.setUntMis(UtilityResources.getString(R.string.unt_mis_col));

                        accettazioneOrdiniPickingListModel.setSecQtaEvasa(qtaEvasa);
                        accettazioneOrdiniPickingListModel.setSecQtaTot(x.getSitArtOrdDTO().getQtaDaEvadere());
                        if (x.getMtbAart() != null)
                            accettazioneOrdiniPickingListModel.setSecUntMis(x.getMtbAart().getUntMis());
                    } else {
                        accettazioneOrdiniPickingListModel.setQtaEvasa(qtaEvasa);
                        accettazioneOrdiniPickingListModel.setQtaTot(x.getSitArtOrdDTO().getQtaDaEvadere());
                        if (x.getMtbAart() != null)
                            accettazioneOrdiniPickingListModel.setUntMis(x.getMtbAart().getUntMis());

                        accettazioneOrdiniPickingListModel.setSecQtaEvasa(numCnfEvasa);
                        accettazioneOrdiniPickingListModel.setSecQtaTot(x.getSitArtOrdDTO().getNumCnfDaEvadere());
                        accettazioneOrdiniPickingListModel.setSecUntMis(UtilityResources.getString(R.string.unt_mis_col));
                    }

                    accettazioneOrdiniPickingListModel.setDescrizione(x.getSitArtOrdDTO().getDescrizioneEstesaOrd());

                    if (x.getMtbAart() != null) {
                        accettazioneOrdiniPickingListModel.setPosizione(x.getMtbAart().getPosizione());
                    }

                    accettazioneOrdiniPickingListModel.setOriginalModel(x);

                    list.add(accettazioneOrdiniPickingListModel);
                });

        Stream.of(dataList)
                .filter(x -> UtilityString.isNullOrEmpty(x.getSitArtOrdDTO().getDescrizioneCommessa()) || x.getSitArtOrdDTO().getCodJcom().equalsIgnoreCase(CommonConst.Config.COMMESSA_MAG))
                .forEach(x -> {
                    AccettazioneOrdiniPickingListModel accettazioneOrdiniPickingListModel = new AccettazioneOrdiniPickingListModel();
                    accettazioneOrdiniPickingListModel.setActive(true);

                    accettazioneOrdiniPickingListModel.setGroupTitle(UtilityString.isNull(x.getSitArtOrdDTO().getCodJcom(), CommonConst.Config.COMMESSA_MAG));

                    accettazioneOrdiniPickingListModel.setBadge1(UtilityString.isNull(x.getSitArtOrdDTO().getCodArtFor(), x.getSitArtOrdDTO().getCodMart()));
                    accettazioneOrdiniPickingListModel.setBadge2(String.valueOf(x.getSitArtOrdDTO().getNumOrd()));


                    //Calc Num CNF
                    BigDecimal numCnfEvasa = BigDecimal.ZERO;

                    if (x.getWithdrawMtbColrs().size() > 0) {
                        numCnfEvasa = Stream.of(x.getWithdrawMtbColrs())
                                .map(MtbColr::getNumCnf)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                    }

                    //Calc qta col
                    BigDecimal qtaEvasa = BigDecimal.ZERO;

                    if (x.getWithdrawMtbColrs().size() > 0) {
                        qtaEvasa = Stream.of(x.getWithdrawMtbColrs())
                                .map(MtbColr::getQtaCol)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                    }


                    if (SettingsManager.iDB().isFlagForceAllToColli() || (x.getMtbAart() == null || !x.getMtbAart().isFlagQtaCnfFissaBoolean())) {
                        accettazioneOrdiniPickingListModel.setQtaEvasa(numCnfEvasa);
                        accettazioneOrdiniPickingListModel.setQtaTot(x.getSitArtOrdDTO().getNumCnfDaEvadere());
                        accettazioneOrdiniPickingListModel.setUntMis(UtilityResources.getString(R.string.unt_mis_col));

                        accettazioneOrdiniPickingListModel.setSecQtaEvasa(qtaEvasa);
                        accettazioneOrdiniPickingListModel.setSecQtaTot(x.getSitArtOrdDTO().getQtaDaEvadere());
                        if (x.getMtbAart() != null)
                            accettazioneOrdiniPickingListModel.setSecUntMis(x.getMtbAart().getUntMis());
                    } else {
                        accettazioneOrdiniPickingListModel.setQtaEvasa(qtaEvasa);
                        accettazioneOrdiniPickingListModel.setQtaTot(x.getSitArtOrdDTO().getQtaDaEvadere());
                        if (x.getMtbAart() != null)
                            accettazioneOrdiniPickingListModel.setUntMis(x.getMtbAart().getUntMis());

                        accettazioneOrdiniPickingListModel.setSecQtaEvasa(numCnfEvasa);
                        accettazioneOrdiniPickingListModel.setSecQtaTot(x.getSitArtOrdDTO().getNumCnfDaEvadere());
                        accettazioneOrdiniPickingListModel.setSecUntMis(UtilityResources.getString(R.string.unt_mis_col));
                    }


                    if (x.getMtbAart() != null) {
                        accettazioneOrdiniPickingListModel.setDescrizione(x.getMtbAart().getDescrizioneEstesa());
                        accettazioneOrdiniPickingListModel.setUntMis(x.getMtbAart().getUntMis());
                    }

                    accettazioneOrdiniPickingListModel.setOriginalModel(x);

                    list.add(accettazioneOrdiniPickingListModel);
                });

        return list;
    }

    private boolean isThereAnyItemToPick(List<PickingObjectDTO> dataList) {
        return Stream.of(dataList)
                .anyMatch(x -> !x.isHidden());
    }

    private final RunnableArgs<BarcodeScanDTO> onScanSuccessful = data -> {
        this.onLoadingStarted();

        this.mViewModel.processBarcodeDTO(data, () -> {
            this.onLoadingEnded();
        });
    };


    public void showFabMenu() {
        fabPopupMenu.show();
    }

    public void createNewLU() {
        this.fabPopupMenu.dismiss();
        this.onLoadingStarted();

        this.mViewModel.createNewLU(null, null, false, () -> {
            this.onLoadingEnded();
        });
    }

    public void showCreatedUL() {
        this.fabPopupMenu.dismiss();
        this.mViewModel.retrieveExistentLU(this::startListaBancaliRegistratiActivity);
    }

    private void showOrderByDialog() {
        AlertDialog dialog = new AlertDialog.Builder(this)
                .setTitle(this.getText(R.string.action_orderBy))
                .setSingleChoiceItems(AccettazioneOrdineInevasoOrderBy.descriptions, mCurrentOrderBy.getVal(), (dialog12, which) -> {
                    mCurrentOrderBy = AccettazioneOrdineInevasoOrderBy.Enum.fromInt(which);
                    SettingsManager.i().getUserSession().setDefaultOrdinamentoPickingAccettazione(which);
                })
                .setPositiveButton(getText(R.string.ok), (dialog1, which) -> this.refreshList())
                .create();
        dialog.show();
    }

    public void startListaBancaliRegistratiActivity(List<AlreadyRegisteredUDCDTO> mtbColts) {

        Intent myIntent = ListaBancaliActivity.createIntent(this,

                Stream.of(mtbColts)
                        .map(AlreadyRegisteredUDCDTO::getMtbColt)
                        .toList(),

                input -> Stream.of(mtbColts)
                        .filter(x -> x.getMtbColt() == input)
                        .findFirstOrElse(null)
                        .isCanBeRecovered(),

                ReportManager.getReportNameLUFromGestione(GestioneEnum.ACQUISTO));

        this.startActivityForResult(myIntent, PICK_UL_REQUEST);
    }

    @Override
    public void onLUSuccessullyPrinted() {
        Resources res = getResources();
        String errorMessage = res.getText(R.string.alert_print_completed_message).toString();
        DialogSimpleMessageView
                .makeSuccessDialog(res.getText(R.string.completed).toString(), new SpannableString(errorMessage), null, null)
                .show(getSupportFragmentManager(), "tag");
    }

    @Override
    public void onLUPrintRequest(RunnableArgs<Boolean> onComplete) {
    }

    @Override
    public void onLUPrintError(Exception ex, Runnable onComplete) {
        this.onLoadingEnded();
        DialogSimpleMessageView.makeErrorDialog(
                        new SpannableString(ex.getMessage()),
                        null,
                        null,
                        R.string.button_ignore_print,
                        onComplete)
                .show(getSupportFragmentManager(), "tag");
    }

    @Override
    public void onMtbColrEdit(MtbColr mtbColr) {
        this.mViewModel.dispatchRowEdit(mtbColr);
    }

    @Override
    public void onMtbColrDelete(MtbColr mtbColr) {
        this.mViewModel.deleteRow(mtbColr);
    }

    @Override
    public void onBottomSheetLUClose() {
        this.mViewModel.closeLU();
    }

    @Override
    public void onVersamentoAutomaticoULRequest(RunnableArgs<Boolean> onComplete) {
        runOnUiThread(() -> {
            DialogAskShouldVersamentoAutomaticoULView.newInstance(onComplete)
                    .show(getSupportFragmentManager(), "tag");
        });
    }

    @Override
    public void onInfoAggiuntiveRequest(RunnableArgss<String, MtbTCol> onComplete) {
//        runOnUiThread(() -> {
//            DialogInfoAggiuntiveLU.newInstance(onComplete).show(getSupportFragmentManager(), "InfoAggiuntiveLUDialog");
//        });

        DialogInfoAggiuntiveLUView.newInstance(onComplete, this::onLoadingEnded)
                .show(getSupportFragmentManager(), DialogInfoAggiuntiveLUView.class.getName());
    }

    @Override
    public void onError(Exception ex) {
        this.onLoadingEnded();

        if (ex instanceof InvalidPesoKGException) {
            UtilityToast.showToast(ex.getMessage());
        } else {
            UtilityExceptions.defaultException(this, ex);
        }

        BarcodeManager.enable();
    }

    @Override
    public void onItemDispatched(PickingObjectDTO pickingObjectDTO, MtbAart mtbAart, BigDecimal initialNumCnf, BigDecimal initialQtaCnf, BigDecimal initialQtaTot, BigDecimal totalQtaOrd, BigDecimal totalNumCnfOrd, BigDecimal qtaCnfOrd, BigDecimal totalQtaToBeTaken, BigDecimal totalNumCnfToBeTaken, BigDecimal qtaCnfToBeTaken, BigDecimal totalQtaAvailable, BigDecimal totalNumCnfAvailable, BigDecimal qtaCnfAvailable, String partitaMag, LocalDate dataScad, boolean canPartitaMagBeChanged, boolean canOverflowQuantity, String customArtDescription, RunnableArgss<PickedQuantityDTO, Boolean> onComplete) {
        DialogInputQuantityV2DTO dialogInputQuantityV2DTO = new DialogInputQuantityV2DTO()
                .setMtbAart(mtbAart)
                .setInitialNumCnf(initialNumCnf)
                .setInitialQtaCnf(initialQtaCnf)
                .setInitialQtaTot(initialQtaTot)
                .setTotalQtaOrd(totalQtaOrd)
                .setTotalNumCnfOrd(totalNumCnfOrd)
                .setQtaCnfOrd(qtaCnfOrd)
                .setTotalQtaToBeTaken(totalQtaToBeTaken)
                .setTotalNumCnfToBeTaken(totalNumCnfToBeTaken)
                .setQtaCnfToBeTaken(qtaCnfToBeTaken)
                .setTotalQtaAvailable(totalQtaAvailable)
                .setTotalNumCnfAvailable(totalNumCnfAvailable)
                .setQtaCnfAvailable(qtaCnfAvailable)
                .setPartitaMag(partitaMag)
                .setDataScad(dataScad)
                .setCanPartitaMagBeChanged(canPartitaMagBeChanged)
                .setCanLUBeClosed(true)
                .setCanOverflowOrderQuantity(canOverflowQuantity)
                .setCustomArtDescription(customArtDescription);

        if (!mDialogInputQuantityV2View.isVisible())
            mDialogInputQuantityV2View
                    .setDialogInputQuantityV2DTO(dialogInputQuantityV2DTO)
                    .setOnComplete((resultDTO, shouldCloseLU) -> {
                        PickedQuantityDTO pickedQuantityDTO = new PickedQuantityDTO()
                                .setNumCnf(resultDTO.getNumCnf())
                                .setQtaCnf(resultDTO.getQtaCnf())
                                .setQtaTot(resultDTO.getQtaTot())
                                .setPartitaMag(resultDTO.getPartitaMag())
                                .setDataScad(resultDTO.getDataScad());
                        onComplete.run(pickedQuantityDTO, shouldCloseLU);
                    })
                    .setOnAbort(() -> this.mViewModel.resetMatchedRows())
                    .show(getSupportFragmentManager(), "tag");
    }

    @Override
    public void onRowSaved() {
        runOnUiThread(() -> {
            FBToast.successToast(this, getResources().getString(R.string.data_saved), FBToast.LENGTH_SHORT);
        });
    }

    @Override
    public void onFilterCodMartApplied(String codMartToFilter) {
        runOnUiThread(() -> {
            var codMarts = new ArrayList<String>();
            codMarts.add(codMartToFilter);

            this.mAppliedFilterViewModel.setCodArtFilter(codMarts);
        });
    }

    @Override
    public void onFilterPosizioneApplied(String posizioneToFilter) {
        runOnUiThread(() -> {
            var posizioni = new ArrayList<String>();
            posizioni.add(posizioneToFilter);

            this.mAppliedFilterViewModel.setPosFilter(posizioni);
        });
    }

    @Override
    public void onULVersata(VersamentoAutomaticoULResponseDTO versamentoAutomaticoULResponseDTO, Runnable onComplete) {

        runOnUiThread(() -> {
            DialogVersamentoAutomaticoULDoneView
                    .newInstance(versamentoAutomaticoULResponseDTO, onComplete)
                    .show(getSupportFragmentManager(), "tag");
        });

    }

    @Override
    public void onMtbColrDeleteRequest(RunnableArgs<Boolean> onComplete) {
        runOnUiThread(() -> {
            String text = getResources().getString(R.string.alert_delete_mtb_colr);
            DialogSimpleMessageView.makeWarningDialog(new SpannableString(text),
                    null,
                    () -> onComplete.run(true),
                    () -> onComplete.run(false)
            ).show(getSupportFragmentManager(), "tag");
        });
    }

    @Override
    public void onLUOpened(MtbColt mtbColt) {
        runOnUiThread(() -> {
            noLUPresent.set(false);
            FBToast.successToast(this, getResources().getString(R.string.data_saved), FBToast.LENGTH_SHORT);

            this.mBottomSheetFragmentLUContentViewModel.setMtbColt(mtbColt);
        });
    }

    @Override
    public void onLUClosed() {
        runOnUiThread(() -> {
            noLUPresent.set(true);
            this.mBottomSheetFragmentLUContentViewModel.setMtbColt(null);

            if (this.mShouldCloseActivity) super.onBackPressed();
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Check which request we're responding to
        if (requestCode == PICK_UL_REQUEST) {

            // Make sure the request was successful
            if (resultCode == RESULT_OK) {
                MtbColt recoveredMtbColt = DataCache.retrieveItem(data.getStringExtra("key"));
                this.mViewModel.recoverLU(recoveredMtbColt);
            }
        }
    }
}
