package it.integry.integrywmsnative.gest.prod_fabbisogno_linee_prod;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.annimon.stream.Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import it.integry.integrywmsnative.core.data_store.db.entity.InventarioRoomDTO;
import it.integry.integrywmsnative.core.exception.NoOrdersScheduledException;
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.interfaces.viewmodel_listeners.ILoadingListener;
import it.integry.integrywmsnative.core.rest.consumers.MesRESTConsumer;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import it.integry.integrywmsnative.gest.prod_fabbisogno_linee_prod.dto.GroupTitleModel;
import it.integry.integrywmsnative.gest.prod_fabbisogno_linee_prod.dto.ProdFabbisognoLineeItemModelDto;
import it.integry.integrywmsnative.gest.prod_fabbisogno_linee_prod.dto.ProdFabbisognoLineeProdDTO;
import it.integry.integrywmsnative.gest.prod_fabbisogno_linee_prod.rest.ProdFabbisognoLineeProdRESTConsumer;
import it.integry.integrywmsnative.gest.prod_versamento_materiale.dto.OrdineLavorazioneDTO;

public class ProdFabbisognoLineeProdViewModel {

    private final ProdFabbisognoLineeProdRESTConsumer mProdFabbisognoLineeProdRESTConsumer;

    private final MesRESTConsumer mMesRESTConsumer;

    private Listener mListener;

    private final MutableLiveData<List<ProdFabbisognoLineeItemModelDto>> ordiniList = new MutableLiveData<>();

    public ProdFabbisognoLineeProdViewModel(
            ProdFabbisognoLineeProdRESTConsumer prodFabbisognoLineeProdRESTConsumer,
            MesRESTConsumer mesRESTConsumer) {
        this.mProdFabbisognoLineeProdRESTConsumer = prodFabbisognoLineeProdRESTConsumer;
        this.mMesRESTConsumer = mesRESTConsumer;
    }

    public void init() {
        loadData();
    }

    public void loadData() {
        this.sendOnLoadingStarted();

        this.mMesRESTConsumer.getOrdiniLavorazione("I", ordini -> {

            List<ProdFabbisognoLineeItemModelDto> itemModel = Stream.of(ordini)
                    .filter(x -> x.getCodMdep().equals(SettingsManager.i().getUserSession().getDepo().getCodMdep()))
                    .map(ord -> new ProdFabbisognoLineeItemModelDto()
                            .setOrdineLavorazioneDTO(ord)
                    )
                    .sorted(Comparator.comparing(x -> x.getOrdineLavorazioneDTO().getCodJfas()))
                    .toList();

            ordiniList.postValue(itemModel);
            this.sendOnLoadingEnded();
        }, this::sendError);
    }

    public LiveData<List<ProdFabbisognoLineeItemModelDto>> getOrdiniList() {
        return ordiniList;
    }

    public void loadFabbisogno(String ordini, String codMdep, Date dataInizio, Date dataFine, RunnableArgs<List<ProdFabbisognoLineeProdDTO>> onComplete) {
        this.sendOnLoadingStarted();

        this.mProdFabbisognoLineeProdRESTConsumer.loadFabbisogno(ordini, codMdep, jtbFasi -> {
            if (jtbFasi == null) jtbFasi = new ArrayList<>();

            Stream.of(jtbFasi)
                    .forEach(x -> {
                        x.setDataInizio(dataInizio);
                        x.setDataFine(dataFine);
                    });

            this.sendOnLoadingEnded();
            onComplete.run(jtbFasi);
        }, this::sendError);
    }


    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 setListener(Listener listener) {
        this.mListener = listener;
    }

    public interface Listener extends ILoadingListener {

        void onError(Exception ex);

    }

}
