package it.integry.integrywmsnative.core.rest.consumers;

import android.util.Log;

import com.annimon.stream.Stream;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.inject.Singleton;

import it.integry.integrywmsnative.core.data_store.db.entity.ArticoloOrdine;
import it.integry.integrywmsnative.core.data_store.db.entity.Griglia;
import it.integry.integrywmsnative.core.data_store.db.entity.Ordine;
import it.integry.integrywmsnative.core.data_store.db.view_model.ArticoloDTO;
import it.integry.integrywmsnative.core.data_store.db.view_model.GrigliaDTO;
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.model.DtbOrdt;
import it.integry.integrywmsnative.core.rest.RESTBuilder;
import it.integry.integrywmsnative.core.rest.model.ServiceRESTResponse;
import it.integry.integrywmsnative.core.utility.UtilityDate;
import it.integry.integrywmsnative.core.utility.UtilityLogger;
import it.integry.integrywmsnative.core.utility.UtilityThread;
import it.integry.integrywmsnative.gest.pv_ordine_acquisto_edit.dto.ArtDTO;
import it.integry.integrywmsnative.gest.pv_ordine_acquisto_edit.dto.OrdineDTO;
import it.integry.integrywmsnative.gest.pv_ordine_acquisto_edit.dto.SaveDTO;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

@Singleton
public class PVOrdiniAcquistoRESTConsumer extends _BaseRESTConsumer {


    public void getArticoliListino(String codAlis, RunnableArgs<GrigliaDTO> onSuccess, RunnableArgs<Exception> onFailed) {
        getArticoliListinoStatic(codAlis, onSuccess, onFailed);
    }

    public static void getArticoliListinoStatic(String codAlis, RunnableArgs<GrigliaDTO> onSuccess, RunnableArgs<Exception> onFailed) {
        PVOrdiniAcquistoRESTConsumerService ordiniARestService = RESTBuilder.getService(PVOrdiniAcquistoRESTConsumerService.class);
        ordiniARestService
                .getArticoliListino(codAlis)
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<GrigliaDTO>> call, Response<ServiceRESTResponse<GrigliaDTO>> response) {
                        analyzeAnswer(response, "getArticoliListino", griglia -> {

                            UtilityThread.executeParallel(() -> {
                                var startTime = new Date().getTime();

                                List<ArticoloDTO> listaArticoli = new ArrayList<>();

                                Stream.of(griglia.getGrigliaAcquistiChild())
                                        .groupBy(ArticoloDTO::getCodMart)
                                        .forEach(entry -> {

                                            if (entry.getValue().size() == 1) {
                                                listaArticoli.add(entry.getValue().get(0));
                                            } else {
                                                for (ArticoloDTO articolo : entry.getValue()) {
                                                    if (!articolo.getBarCode().endsWith(articolo.getCodMart())) {
                                                        listaArticoli.add(articolo);
                                                    }
                                                }
                                            }

                                        });

                                griglia.setGrigliaAcquistiChild(listaArticoli);

                                Log.d("LOADING TIME 1", "MS: " + (new Date().getTime() - startTime));
                                onSuccess.run(griglia);
                            }, false);
                        }, onFailed);
                    }

                    @Override
                    public void onFailure(Call<ServiceRESTResponse<GrigliaDTO>> call, Throwable t) {
                        Log.e("getArticoliListino_pv", t.toString());
                        UtilityLogger.errorMe(new Exception(t));
                        onFailed.run(new Exception(t));
                    }
                });
    }

    public void saveOrdine(Ordine ordine, List<ArticoloOrdine> articoli, Griglia griglia, RunnableArgs<Ordine> onSuccess, RunnableArgs<Exception> onFailed) {
        SaveDTO saveDTO = new SaveDTO();
        OrdineDTO ordineDTO = new OrdineDTO();
        List<ArtDTO> artRows = new ArrayList<>();

        int i = 0;
        for (ArticoloOrdine art : articoli) {
            i++;
            artRows.add(convertArtToDTO(art, i));
        }

        ordineDTO.setChiaveGriglia(griglia.getCodAlis());
        ordineDTO.setDataConsD(UtilityDate.getDateInstance());
        ordineDTO.setArtRows(artRows);
        saveDTO.setGestione("O");
        saveDTO.setOrdineDTO(ordineDTO);


        PVOrdiniAcquistoRESTConsumerService ordiniARestService = RESTBuilder.getService(PVOrdiniAcquistoRESTConsumerService.class);
        ordiniARestService
                .saveOrdine(saveDTO)
                .enqueue(new Callback<List<ServiceRESTResponse<DtbOrdt>>>() {
                    @Override
                    public void onResponse(Call<List<ServiceRESTResponse<DtbOrdt>>> call, Response<List<ServiceRESTResponse<DtbOrdt>>> response) {
                        if (response.body() != null && response.body().size() > 0) {
                            analyzeListOfAnswers(response, "getArticoliListino", dtoList -> {
                                if (dtoList.size() > 0) {
                                    DtbOrdt dto = dtoList.get(0);
                                    ordine.setTransmitted(true);
                                    ordine.setTransmissionDate(UtilityDate.getDateInstance());
                                    ordine.setGestione(dto.getGestione());
                                    ordine.setDataOrdS(dto.getDataOrd());
                                    ordine.setCodMdep(dto.getCodMdep());
                                    ordine.setNumOrd(dto.getNumOrd());
                                    onSuccess.run(ordine);
                                } else {
                                    onFailed.run(new Exception("Nessun ordine generato"));
                                }
                            }, onFailed);
                        }
                    }

                    @Override
                    public void onFailure(Call<List<ServiceRESTResponse<DtbOrdt>>> call, Throwable t) {
                        Log.e("saveOrdineTerminale_pv", t.toString());
                        UtilityLogger.errorMe(new Exception(t));
                        onFailed.run(new Exception(t));
                    }
                });


    }

    private ArtDTO convertArtToDTO(ArticoloOrdine art, int rigaOrd) {
        ArtDTO dto = new ArtDTO();
        dto.setRigaOrd(rigaOrd);
        dto.setCodMart(art.getCodMart());
        dto.setBarcode(art.getBarCode());
        dto.setDescrizione(art.getDescrizione());
        dto.setDataInsD(art.getDataIns());
        dto.setUntMis(art.getUntMis());
        dto.setSystemNote(art.getSystemNote());
        dto.setQta(BigDecimal.valueOf(art.getQtaOrd()));
        dto.setQtaCnf(BigDecimal.valueOf(art.getQtaCnf()));
        dto.setColli(BigDecimal.ZERO);
        return dto;
    }

}
