package it.integry.integrywmsnative.gest.prod_versamento_materiale_su_mag_prossimita;

import androidx.lifecycle.MutableLiveData;

import java.math.BigDecimal;

import javax.inject.Inject;

import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.interfaces.viewmodel_listeners.ILoadingListener;
import it.integry.integrywmsnative.core.model.MtbColr;
import it.integry.integrywmsnative.core.model.MtbColt;
import it.integry.integrywmsnative.core.model.MtbDepoPosizione;
import it.integry.integrywmsnative.core.rest.consumers.MagazzinoBufferRESTConsumer;
import it.integry.integrywmsnative.core.rest.model.magazzino_buffer.MagazzinoBufferVersamentoMaterialeCloseRequestDTO;
import it.integry.integrywmsnative.core.rest.model.magazzino_buffer.MagazzinoBufferVersamentoMaterialeRequestDTO;

public class ProdVersamentoMaterialeInBufferViewModel {

    private final MagazzinoBufferRESTConsumer magazzinoBufferRESTConsumer;

    private ProdVersamentoMaterialeInBufferViewModel.Listener mListener;

    private final MutableLiveData<MtbColt> mtbColtMutableLiveData = new MutableLiveData<>();

    @Inject
    public ProdVersamentoMaterialeInBufferViewModel(MagazzinoBufferRESTConsumer magazzinoBufferRESTConsumer) {
        this.magazzinoBufferRESTConsumer = magazzinoBufferRESTConsumer;
    }


    public MutableLiveData<MtbColt> getMtbColtMutable() {
        return mtbColtMutableLiveData;
    }

    public MtbColr getMtbColr() {
        MtbColt mtbColt = mtbColtMutableLiveData.getValue();
        if(mtbColt == null || mtbColt.getMtbColr() == null || mtbColt.getMtbColr().isEmpty()) return null;

        return mtbColt.getMtbColr().get(0);
    }

    public void setMtbColt(MtbColt mtbColt) {
        this.mtbColtMutableLiveData.setValue(mtbColt);
    }

    public void setPosizione(MtbDepoPosizione mtbDepoPosizione, Runnable onComplete) {
        this.sendOnLoadingStarted();

        var magazzinoRequest = new MagazzinoBufferVersamentoMaterialeRequestDTO()
                .setInputMtbColt(mtbColtMutableLiveData.getValue());

        magazzinoBufferRESTConsumer.isVersamentoStarted(mtbDepoPosizione, magazzinoRequest, versamentoStarted -> {

            if (!versamentoStarted) {
                magazzinoBufferRESTConsumer.startVersamentoMateriale(mtbDepoPosizione, magazzinoRequest, () -> {
                    this.sendOnLoadingEnded();
                    onComplete.run();
                }, this::sendError);
            } else {
                this.sendOnRequestColliQuantityToConfirm(inputQuantity -> {
                    if(inputQuantity == null) {
                        this.sendOnLoadingEnded();
                        onComplete.run();
                        return;
                    }

                    var closeRequest = new MagazzinoBufferVersamentoMaterialeCloseRequestDTO()
                            .setInputMtbColt(mtbColtMutableLiveData.getValue())
                            .setNumCnfDaScaricare(inputQuantity);

                    magazzinoBufferRESTConsumer.endVersamentoMateriale(mtbDepoPosizione, closeRequest, () -> {
                        this.sendOnLoadingEnded();
                        onComplete.run();
                    }, this::sendError);
                });

            }
        }, this::sendError);
    }


    public ProdVersamentoMaterialeInBufferViewModel setListener(ProdVersamentoMaterialeInBufferViewModel.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 sendOnRequestColliQuantityToConfirm(RunnableArgs<BigDecimal> onComplete) {
        if (this.mListener != null) mListener.onRequestColliQuantityToConfirm(onComplete);
    }

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

    public interface Listener extends ILoadingListener {
        void onRequestColliQuantityToConfirm(RunnableArgs<BigDecimal> onComplete);

        void onError(Exception ex, boolean requestClose);
    }
}