package it.integry.integrywmsnative.gest.rettifica_giacenze.rest;

import com.annimon.stream.Stream;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.inject.Singleton;

import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.model.MtbAart;
import it.integry.integrywmsnative.core.model.MtbColt;
import it.integry.integrywmsnative.core.rest.RESTBuilder;
import it.integry.integrywmsnative.core.rest.consumers.SystemRESTConsumer;
import it.integry.integrywmsnative.core.rest.consumers._BaseRESTConsumer;
import it.integry.integrywmsnative.core.rest.model.SaveDocFromPickingRequestDTO;
import it.integry.integrywmsnative.core.rest.model.ServiceRESTResponse;
import it.integry.integrywmsnative.gest.rettifica_giacenze.dto.FornitoreDTO;
import it.integry.integrywmsnative.gest.rettifica_giacenze.dto.SearchArticoloByBarcodeOrCodMartRequestDTO;
import it.integry.integrywmsnative.gest.rettifica_giacenze.dto.SearchArticoloByBarcodeOrCodMartResponseDTO;
import it.integry.integrywmsnative.gest.rettifica_giacenze.dto.SearchArticoloByCodArtFornOrDescrizioneRequestDTO;
import it.integry.integrywmsnative.gest.rettifica_giacenze.dto.SearchArticoloByCodArtFornOrDescrizioneResponseDTO;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

@Singleton
public class RettificaGiacenzeRESTConsumer extends _BaseRESTConsumer {

    private final SystemRESTConsumer mSystemRestConsumer;

    public RettificaGiacenzeRESTConsumer(SystemRESTConsumer systemRestConsumer) {
        mSystemRestConsumer = systemRestConsumer;
    }

    public void loadListaFornitori(RunnableArgs<ArrayList<FornitoreDTO>> onComplete, RunnableArgs<Exception> onFailed) {
        String sql = "SELECT cod_alis as 'codAlis', descrizione FROM atb_list WHERE flag_attivo = 'S'";

        Type typeOfObjectsList = new TypeToken<ArrayList<FornitoreDTO>>() {
        }.getType();

        mSystemRestConsumer.<ArrayList<FornitoreDTO>>processSql(sql, typeOfObjectsList, value -> {
            if (onComplete != null) onComplete.run(value);
        }, onFailed);
    }


    public void searchArtForn(String codAlis, String codArtForOrDescr, RunnableArgs<List<SearchArticoloByCodArtFornOrDescrizioneResponseDTO>> onComplete, RunnableArgs<Exception> onError) {
        final RettificaGiacenzeRESTConsumerService service = RESTBuilder.getService(RettificaGiacenzeRESTConsumerService.class);
        service.searchByCodArtFornOrDescrizione(new SearchArticoloByCodArtFornOrDescrizioneRequestDTO()
                        .setCodAlis(codAlis)
                        .setCodArtFornOrDescrizione(codArtForOrDescr))
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<List<SearchArticoloByCodArtFornOrDescrizioneResponseDTO>>> call,
                                           Response<ServiceRESTResponse<List<SearchArticoloByCodArtFornOrDescrizioneResponseDTO>>> response) {
                        analyzeAnswer(response, "searchByCodArtFornOrDescrizione", onComplete, onError);
                    }

                    @Override
                    public void onFailure(Call<ServiceRESTResponse<List<SearchArticoloByCodArtFornOrDescrizioneResponseDTO>>> call, Throwable t) {
                        onError.run(new Exception(t));
                    }
                });



    }


    public void searchArtInt(String codMartOrBarcodeOrDescr, RunnableArgs<List<MtbAart>> onComplete, RunnableArgs<Exception> onError) {
        final RettificaGiacenzeRESTConsumerService service = RESTBuilder.getService(RettificaGiacenzeRESTConsumerService.class);
        service.searchByCodMartOrBarcode(new SearchArticoloByBarcodeOrCodMartRequestDTO()
                        .setCodMartOrBarcode(codMartOrBarcodeOrDescr))
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<List<SearchArticoloByBarcodeOrCodMartResponseDTO>>> call,
                                           Response<ServiceRESTResponse<List<SearchArticoloByBarcodeOrCodMartResponseDTO>>> response) {
                        analyzeAnswer(response, "searchByCodMartOrBarcode", data -> {

                            var listToReturn = Stream.of(data)
                                            .map(x -> x.getMtbAart()
                                                    .setQtaEsistente(x.getQtaEsistente())
                                                    .setQtaImpegnata(x.getQtaImpegnata())
                                                    .setNumCnfEsistente(x.getNumCnfEsistente())
                                                    .setNumCnfImpegnata(x.getNumCnfImpegnata()))
                                                    .toList();

                            onComplete.run(listToReturn);
                        }, onError);
                    }

                    @Override
                    public void onFailure(Call<ServiceRESTResponse<List<SearchArticoloByBarcodeOrCodMartResponseDTO>>> call, Throwable t) {
                        onError.run(new Exception(t));
                    }
                });
    }


    public void saveDoc(MtbColt mtbColt, Runnable onComplete, RunnableArgs<Exception> onError) {

        var request = new SaveDocFromPickingRequestDTO()
                .setColliFromMtbColts(Collections.singletonList(mtbColt));

        final RettificaGiacenzeRESTConsumerService service = RESTBuilder.getService(RettificaGiacenzeRESTConsumerService.class);
        service.saveDocFromPickingPvm(request)
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<Void>> call, Response<ServiceRESTResponse<Void>> response) {
                        analyzeAnswerList(response, "saveDocFromPickingPvm", data -> onComplete.run(), onError);
                    }

                    @Override
                    public void onFailure(Call<ServiceRESTResponse<Void>> call, Throwable t) {
                        onError.run(new Exception(t));
                    }
                });
    }

}
