package it.integry.integrywmsnative.gest.ultimi_arrivi_fornitore;

import androidx.lifecycle.MutableLiveData;

import java.util.List;

import javax.inject.Inject;

import it.integry.barcode_base_android_library.model.BarcodeScanDTO;
import it.integry.integrywmsnative.core.exception.InvalidLUException;
import it.integry.integrywmsnative.core.exception.NoLUFoundException;
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.interfaces.viewmodel_listeners.ILoadingListener;
import it.integry.integrywmsnative.core.model.GtbAnag;
import it.integry.integrywmsnative.core.model.MtbAart;
import it.integry.integrywmsnative.core.model.MtbColt;
import it.integry.integrywmsnative.core.rest.consumers.BarcodeRESTConsumer;
import it.integry.integrywmsnative.core.rest.consumers.ColliMagazzinoRESTConsumer;
import it.integry.integrywmsnative.core.rest.model.DocumentoResoDTO;
import it.integry.integrywmsnative.core.utility.UtilityBarcode;
import it.integry.integrywmsnative.core.utility.UtilityString;
import it.integry.integrywmsnative.gest.ultimi_arrivi_fornitore.rest.UltimiArriviFornitoreRESTConsumer;

public class UltimiArriviFornitoreViewModel {

    private final MutableLiveData<List<GtbAnag>> mGtbAnagClienti = new MutableLiveData<>();
    private final MutableLiveData<List<DocumentoResoDTO>> mDocuments = new MutableLiveData<>();

    private final UltimiArriviFornitoreRESTConsumer mUltimiArriviFornitoreRESTConsumer;
    private final BarcodeRESTConsumer mBarcodeRESTConsumer;
    private final ColliMagazzinoRESTConsumer mColliMagazzinoRESTConsumer;

    private Listener mListener;

    private String mCodMdep;

    @Inject
    public UltimiArriviFornitoreViewModel(
            UltimiArriviFornitoreRESTConsumer ultimiArriviFornitoreRESTConsumer,
            BarcodeRESTConsumer barcodeRESTConsumer,
            ColliMagazzinoRESTConsumer colliMagazzinoRESTConsumer) {
        this.mUltimiArriviFornitoreRESTConsumer = ultimiArriviFornitoreRESTConsumer;
        this.mBarcodeRESTConsumer = barcodeRESTConsumer;
        this.mColliMagazzinoRESTConsumer = colliMagazzinoRESTConsumer;
    }


    public void init(String codMdep) {
        this.mCodMdep = codMdep;
    }


    public void loadCodAnagFornitori(RunnableArgs<List<GtbAnag>> onComplete) {
        this.sendOnLoadingStarted();

        this.mUltimiArriviFornitoreRESTConsumer.getAvailableCodAnagFornitori(gtbAnags -> {
            mGtbAnagClienti.postValue(gtbAnags);
            this.sendOnLoadingEnded();

            onComplete.run(gtbAnags);
        }, this::sendError);
    }

    public void loadArriviFornitori(String codAnag, List<MtbAart> mtbAarts, int limitDocsForCli, int limitDays) {
        this.sendOnLoadingStarted();

        this.mUltimiArriviFornitoreRESTConsumer.getUltimeConsegneFornitori(mCodMdep, codAnag, mtbAarts, limitDocsForCli, limitDays, documentList -> {
            this.mDocuments.postValue(documentList);
            this.sendOnLoadingEnded();
        }, this::sendError);
    }


    public void processBarcodeDTO(BarcodeScanDTO barcodeScanDTO, Runnable onComplete) {

        this.sendOnLoadingStarted();

        Runnable onBarcodeScanComplete = () -> {
            onComplete.run();
            this.sendOnLoadingEnded();
        };

        if (UtilityBarcode.isEtichettaAnonima(barcodeScanDTO)) {
            this.executeEtichettaLU(barcodeScanDTO.getStringValue(), onBarcodeScanComplete);
        } else if (UtilityBarcode.isEtichetta128(barcodeScanDTO)) {
            this.executeEtichettaEan128(barcodeScanDTO, onBarcodeScanComplete);
        } else {
            onComplete.run();
        }
    }


    private void executeEtichettaLU(String SSCC, Runnable onComplete) {
        this.mColliMagazzinoRESTConsumer.getBySSCC(SSCC, true, false, mtbColt -> {

            if(mtbColt != null && mtbColt.getMtbColr() != null && mtbColt.getMtbColr().size() > 0) {
                if(mtbColt.getSegno() > 0) {

                    this.sendOnMtbColtScanned(mtbColt);

//                    this.mOrdiniUscitaElencoRESTConsumer.getOrdiniFromCommessaCollo(mCurrentCodMdep, mtbColt, orderList -> {
//
//                        if(orderList != null && orderList.size() > 0) {
//                            List<Integer> numOrds = Stream.of(orderList)
//                                    .map(DtbOrdt::getNumOrd)
//                                    .toList();
//
//                            List<OrdiniUscitaElencoDTO> filteredOrders = Stream.of(mOrderList.getValue())
//                                    .filter(x -> numOrds.contains(x.getNumOrd())).toList();
//
//                            onComplete.run(filteredOrders);
//                        } else {
//                            this.sendError(new NoOrderFoundException());
//                        }
//
//                    }, this::sendError);
                } else {
                    this.sendError(new InvalidLUException());
                }
            } else {
                this.sendError(new NoLUFoundException());
            }

        }, this::sendError);
    }

    private void executeEtichettaEan128(BarcodeScanDTO barcodeScanDTO, Runnable onComplete) {
        this.mBarcodeRESTConsumer.decodeEan128(barcodeScanDTO, ean128Model -> {
            String barcodeProd = null;

            if (!UtilityString.isNullOrEmpty(ean128Model.Sscc)) barcodeProd = ean128Model.Sscc;
            if (!UtilityString.isNullOrEmpty(ean128Model.Gtin)) barcodeProd = ean128Model.Gtin;
            if (!UtilityString.isNullOrEmpty(ean128Model.Content))
                barcodeProd = ean128Model.Content;


            if (!UtilityString.isNullOrEmpty(barcodeProd)) {

                if (!UtilityString.isNullOrEmpty(ean128Model.Sscc)) {
                    this.executeEtichettaLU(ean128Model.Sscc, onComplete);
                } else {
                    this.sendError(new NoLUFoundException());
                }
            } else {
                //EAN 128 non completo o comunque mancano i riferimenti al prodotto
                this.sendError(new NoLUFoundException());
            }
        }, this::sendError);
    }








    public MutableLiveData<List<GtbAnag>> getGtbAnagClienti() {
        return mGtbAnagClienti;
    }

    public MutableLiveData<List<DocumentoResoDTO>> getDocuments() {
        return mDocuments;
    }

    public UltimiArriviFornitoreViewModel setListener(UltimiArriviFornitoreViewModel.Listener listener) {
        this.mListener = listener;
        return this;
    }

    private void sendOnLoadingStarted() {
        if (this.mListener != null) mListener.onLoadingStarted();
    }

    private void sendOnLoadingEnded() {
        if (this.mListener != null) mListener.onLoadingEnded();
    }

    private void sendError(Exception ex) {
        if (this.mListener != null) mListener.onError(ex);
    }

    private void sendOnMtbColtScanned(MtbColt scannedMtbColt) {
        if (this.mListener != null) mListener.onMtbColtScanned(scannedMtbColt);
    }

    public interface Listener extends ILoadingListener {
        void onError(Exception ex);

        void onMtbColtScanned(MtbColt scannedMtbColt);
    }
}
