package it.integry.integrywmsnative.gest.prod_linee_produzione;

import androidx.lifecycle.MutableLiveData;

import com.annimon.stream.Stream;

import java.util.List;

import javax.inject.Inject;

import it.integry.barcode_base_android_library.model.BarcodeScanDTO;
import it.integry.integrywmsnative.core.barcode_reader.BarcodeManager;
import it.integry.integrywmsnative.core.interfaces.viewmodel_listeners.ILoadingListener;
import it.integry.integrywmsnative.core.rest.consumers.ProductionLinesRESTConsumer;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import it.integry.integrywmsnative.gest.prod_linee_produzione.dto.ProdLineStatusDTO;

public class ProdLineeProduzioneViewModel {


    private final ProductionLinesRESTConsumer productionLinesRESTConsumer;
    private final MutableLiveData<List<ProdLineStatusDTO>> prodLines = new MutableLiveData<>();

    private Listener mListener;

    @Inject
    public ProdLineeProduzioneViewModel(ProductionLinesRESTConsumer productionLinesRESTConsumer) {
        this.productionLinesRESTConsumer = productionLinesRESTConsumer;
    }

    public void init() {
        reloadLines();
    }

    private void reloadLines() {
        sendOnLoadingStarted();
        BarcodeManager.disable();
        this.productionLinesRESTConsumer.getStatoLinee(SettingsManager.i().getUserSession().getDepo().getCodMdep(), lineeProdList -> {
            BarcodeManager.enable();
            prodLines.postValue(lineeProdList);
            this.sendOnLoadingEnded();
        }, this::sendError);
    }

    public MutableLiveData<List<ProdLineStatusDTO>> getProdLinesList() {
        return prodLines;
    }

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

    public void processBarcodeDTO(BarcodeScanDTO barcodeScanDTO) {
        String codJfas = barcodeScanDTO.getStringValue();
        ProdLineStatusDTO prodLine = prodLines.getValue() != null ? Stream.of(prodLines.getValue()).filter(x -> x.getCodJfas().equalsIgnoreCase(codJfas)).findFirstOrElse(null) : null;
        if (prodLine != null) {
            this.onLineSelected(prodLine);
        } else {
            this.sendError(new Exception("Linea di produzione " + codJfas + " non trovata"));
        }
    }


    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);
    }

    public void startProductionLine(ProdLineStatusDTO prodLine, Integer hrNum) {
        this.sendOnLoadingStarted();
        this.productionLinesRESTConsumer.avviaLineaDiProduzione(prodLine.getCodJfas(),
                hrNum,
                () -> this.mListener.successDialog("Operazione completata", this::reloadLines),
                this::sendError);
    }

    public void onLineSelected(ProdLineStatusDTO lineSelected) {
        mListener.selectLine(lineSelected);
    }


    public interface Listener extends ILoadingListener {

        void onError(Exception ex);

        void successDialog(String message, Runnable onComplete);

        void selectLine(ProdLineStatusDTO prodLineStatusDTO);

    }


}