package it.integry.integrywmsnative.gest.prod_fabbisogno_linee_prod.filters;

import androidx.databinding.ObservableField;
import androidx.lifecycle.MutableLiveData;

import com.annimon.stream.Stream;
import com.annimon.stream.function.Predicate;

import java.util.List;
import java.util.Objects;

import it.integry.integrywmsnative.gest.prod_fabbisogno_linee_prod.dto.ProdFabbisognoLineeItemModelDto;

public class ProdFabbisognoLineeProdFilterViewModel {
    private final ObservableField<Predicate<ProdFabbisognoLineeItemModelDto>> currentNumOrdsPredicate = new ObservableField<>();

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

    public void init(List<ProdFabbisognoLineeItemModelDto> initialList){
        this.initialList = initialList;
        this.currentList.setValue(this.initialList);
    }

    public MutableLiveData<List<ProdFabbisognoLineeItemModelDto>> getCurrentList() {
        return this.currentList;
    }

    public void setNumOrdFilter(List<Integer> numOrds){
        if (numOrds == null || numOrds.isEmpty()) currentNumOrdsPredicate.set(null);
        else{
            currentNumOrdsPredicate.set(x -> numOrds.contains(x.getOrdineLavorazioneDTO().getNumOrd()));
        }
    }

    public void applyAllTests(){
        List<ProdFabbisognoLineeItemModelDto> returnList = null;

        if (currentNumOrdsPredicate.get() == null){
            returnList = this.initialList;
        }else {
            Stream<ProdFabbisognoLineeItemModelDto> tmpStream = Stream.of(this.initialList)
                    .filter(x -> (currentNumOrdsPredicate.get() == null || (currentNumOrdsPredicate.get().test(x))));

            returnList = tmpStream.toList();
        }

        this.currentList.setValue(returnList);
    }

    public ObservableField<Predicate<ProdFabbisognoLineeItemModelDto>> getCurrentNumOrdsPredicate() {
        return currentNumOrdsPredicate;
    }

    public List<Integer> getAllNumOrds(){
        return Stream
                .of(Objects.requireNonNull(initialList))
                .filter(x -> x.getOrdineLavorazioneDTO().getNumOrd() != null)
                .sortBy(x -> -x.getOrdineLavorazioneDTO().getNumOrd())
                .map(x -> x.getOrdineLavorazioneDTO().getNumOrd() != null ? x.getOrdineLavorazioneDTO().getNumOrd() : null)
                .distinct()
                .toList();
    }

    public List<Integer> getAvailableNumOrds(){
        if (currentNumOrdsPredicate.get() == null) return getAllNumOrds();
        else {
            return Stream.of(this.initialList)
                    .map(x -> x.getOrdineLavorazioneDTO().getNumOrd())
                    .distinct()
                    .toList();
        }
    }
}
