package it.integry.integrywmsnative.gest.prod_rientro_merce.order_detail.rest;

import androidx.databinding.ObservableArrayList;

import com.annimon.stream.Stream;
import com.google.gson.reflect.TypeToken;
import com.orhanobut.logger.Logger;

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

import javax.inject.Inject;
import javax.inject.Singleton;

import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.model.MtbColr;
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.ServiceRESTResponse;
import it.integry.integrywmsnative.core.utility.UtilityDB;
import it.integry.integrywmsnative.core.utility.UtilityQuery;
import it.integry.integrywmsnative.gest.prod_rientro_merce.order_detail.rest.dto.ImportColliDaProduzioneRequestDTO;
import it.integry.integrywmsnative.gest.prod_versamento_materiale.dto.OrdineLavorazioneDTO;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

@Singleton
public class ProdRientroMerceOrderDetailRESTConsumer extends _BaseRESTConsumer {

    private final SystemRESTConsumer systemRESTConsumer;

    @Inject
    public ProdRientroMerceOrderDetailRESTConsumer(SystemRESTConsumer systemRESTConsumer) {
        this.systemRESTConsumer = systemRESTConsumer;
    }


    public void getMtbColtsOfOrder(OrdineLavorazioneDTO ordineLavorazioneDTO, RunnableArgs<List<MtbColt>> onComplete, RunnableArgs<Exception> onFailed) {

        String sql = "SELECT mtb_colr.* " +
                " FROM mtb_colr " +
                " INNER JOIN mtb_colt mc ON mtb_colr.gestione = mc.gestione AND mtb_colr.data_collo = mc.data_collo AND " +
                "                                   mtb_colr.ser_collo = mc.ser_collo AND mtb_colr.num_collo = mc.num_collo " +
                " WHERE " +
                " mtb_colr.num_ord = " + UtilityDB.valueToString(ordineLavorazioneDTO.getNumOrd()) + " AND" +
                " mtb_colr.data_ord = " + UtilityDB.valueToString(ordineLavorazioneDTO.getDataOrdD()) + " AND" +
                " mtb_colr.gestione = 'L' AND" +
                " mc.segno = 1";

        Type typeOfObjectsList = new TypeToken<ArrayList<MtbColr>>() {
        }.getType();
        systemRESTConsumer.<List<MtbColr>>processSql(sql, typeOfObjectsList, mtbColrList -> {


            if (mtbColrList != null && !mtbColrList.isEmpty()) {

                List<HashMap<String, Object>> params = new ArrayList<>();

                for (MtbColr mtbcolr :
                        mtbColrList) {
                    HashMap<String, Object> parm = new HashMap<>();

                    parm.put("data_collo", mtbcolr.getDataColloD());
                    parm.put("gestione", mtbcolr.getGestione());
                    parm.put("ser_collo", mtbcolr.getSerCollo());
                    parm.put("num_collo", mtbcolr.getNumCollo());

                    params.add(parm);
                }

                String mtbColtSql = "SELECT * FROM mtb_colt WHERE " + UtilityQuery.concatFieldListInWhereCond(params) + "";


                Type mtbColtTypeOfObjectsList = new TypeToken<ArrayList<MtbColt>>() {
                }.getType();
                systemRESTConsumer.<List<MtbColt>>processSql(mtbColtSql, mtbColtTypeOfObjectsList, mtbColtList -> {

                    if(mtbColtList == null) mtbColtList = new ArrayList<>();

                    for (MtbColt mtbColt : mtbColtList) {

                        ObservableArrayList<MtbColr> mtbColrsRoAdd = new ObservableArrayList<>();
                        mtbColrsRoAdd.addAll(Stream.of(mtbColrList)
                                .filter(x -> x.getNumCollo().equals(mtbColt.getNumCollo()) &&
                                        x.getDataColloD().compareTo(mtbColt.getDataColloD()) == 0 &&
                                        x.getGestione().equals(mtbColt.getGestione()) &&
                                        x.getSerCollo().equals(mtbColt.getSerCollo()))
                                .toList());

                        mtbColt.setMtbColr(mtbColrsRoAdd);
                    }

                    onComplete.run(mtbColtList);

                }, onFailed);

            } else {
                onComplete.run(new ArrayList<>());
            }


        }, onFailed);
    }




    public void importColloDaProduzione(ImportColliDaProduzioneRequestDTO importColliDaProduzioneRequestDTO, RunnableArgs<MtbColt> onComplete, RunnableArgs<Exception> onFailed) {

        ProdRientroMerceOrderDetailRESTConsumerService service = RESTBuilder.getService(ProdRientroMerceOrderDetailRESTConsumerService.class);
        service.importColloDaProduzione(importColliDaProduzioneRequestDTO).enqueue(new Callback<ServiceRESTResponse<MtbColt>>() {
            @Override
            public void onResponse(Call<ServiceRESTResponse<MtbColt>> call, Response<ServiceRESTResponse<MtbColt>> response) {
                analyzeAnswer(response, "importColliDaProduzione", mtbColt -> {
                    onComplete.run(mtbColt);
                }, ex -> {
                    if(onFailed != null) onFailed.run(ex);
                });
            }

            @Override
            public void onFailure(Call<ServiceRESTResponse<MtbColt>> call, Throwable t) {
                Logger.e(t, "importColliDaProduzione");
                onFailed.run(new Exception(t));
            }
        });
    }


    public void deleteColloDaProduzione(MtbColt mtbColtToDelete, Runnable onComplete, RunnableArgs<Exception> onFailed) {
        ProdRientroMerceOrderDetailRESTConsumerService service = RESTBuilder.getService(ProdRientroMerceOrderDetailRESTConsumerService.class);
        service.deleteColloDaProduzione(mtbColtToDelete).enqueue(new Callback<ServiceRESTResponse<Object>>() {
            @Override
            public void onResponse(Call<ServiceRESTResponse<Object>> call, Response<ServiceRESTResponse<Object>> response) {
                analyzeAnswer(response, "deleteColloDaProduzione", mtbColt -> {
                    onComplete.run();
                }, ex -> {
                    if(onFailed != null) onFailed.run(ex);
                });
            }

            @Override
            public void onFailure(Call<ServiceRESTResponse<Object>> call, Throwable t) {
                Logger.e(t, "deleteColloDaProduzione");
                onFailed.run(new Exception(t));
            }
        });
    }

}
