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

import android.util.Log;

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.Ordine;
import it.integry.integrywmsnative.core.data_store.db.view_model.OrdiniAcquistoGrigliaDTO;
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
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.contab_doc_interni.dto.ArtDTO;
import it.integry.integrywmsnative.gest.contab_doc_interni.dto.OrdineDTO;
import it.integry.integrywmsnative.gest.contab_doc_interni.dto.SaveDTO;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

@Singleton
public class PVOrdiniAcquistoRESTConsumer extends _BaseRESTConsumer {

    private final MagazzinoRESTConsumer magazzinoRESTConsumer;

    public PVOrdiniAcquistoRESTConsumer(MagazzinoRESTConsumer magazzinoRESTConsumer) {
        this.magazzinoRESTConsumer = magazzinoRESTConsumer;
    }

    public void retrieveArticoli(String codAlis, String codMdep, RunnableArgs<OrdiniAcquistoGrigliaDTO> onSuccess, RunnableArgs<Exception> onFailed) {
        PVOrdiniAcquistoRESTConsumerService ordiniARestService = RESTBuilder.getService(PVOrdiniAcquistoRESTConsumerService.class, 300);
        ordiniARestService.retrieveArticoli(codAlis, codMdep, null)
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<OrdiniAcquistoGrigliaDTO>> call, Response<ServiceRESTResponse<OrdiniAcquistoGrigliaDTO>> response) {
                        var startTime = new Date().getTime();
                        analyzeAnswer(response, "retrieveArticoliOrdine", articoliOrdineWrapper -> {
                            UtilityThread.executeParallel(() -> {
                                Log.d("LOADING TIME 1", "MS: " + (new Date().getTime() - startTime));
                                onSuccess.run(articoliOrdineWrapper);
                            }, false);
                        }, onFailed);
                    }

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

    public void retrieveArticolo(String codAlis, String codMdep, String barcode, RunnableArgs<OrdiniAcquistoGrigliaDTO> onSuccess, RunnableArgs<Exception> onFailed) {
        PVOrdiniAcquistoRESTConsumerService ordiniARestService = RESTBuilder.getService(PVOrdiniAcquistoRESTConsumerService.class, 300);
        ordiniARestService.retrieveArticoli(codAlis, codMdep, barcode)
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<OrdiniAcquistoGrigliaDTO>> call, Response<ServiceRESTResponse<OrdiniAcquistoGrigliaDTO>> response) {
                        var startTime = new Date().getTime();
                        analyzeAnswer(response, "retrieveArticoliOrdine", articoliOrdineWrapper -> {
                            UtilityThread.executeParallel(() -> {
                                Log.d("LOADING TIME 1", "MS: " + (new Date().getTime() - startTime));
                                onSuccess.run(articoliOrdineWrapper);
                            }, false);
                        }, onFailed);
                    }

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

    public void saveOrdine(Ordine ordine, List<ArticoloOrdine> articoli, String codMdep, 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(ordine.getCodAlis());
        ordineDTO.setArtRows(artRows);
        saveDTO.setGestione("O");
        saveDTO.setOrdineDTO(ordineDTO);

        PVOrdiniAcquistoRESTConsumerService ordiniARestService = RESTBuilder.getService(PVOrdiniAcquistoRESTConsumerService.class, 300);
        ordiniARestService.save(codMdep, saveDTO)
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<Object>> call, Response<ServiceRESTResponse<Object>> response) {
                        var startTime = new Date().getTime();
                        analyzeAnswer(response, "retrieveArticoliOrdine", articoliOrdineWrapper -> {
                            UtilityThread.executeParallel(() -> {
//                                if (data == null) {
//                                    onFailed.run(new Exception("Nessun ordine generato"));
//                                    return;
//                                }
                                ordine.setTransmitted(true);
                                ordine.setTransmissionDate(UtilityDate.getDateInstance());
//                                ordine.setGestione(data.getGestione());
//                                ordine.setDataOrdS(data.getDataOrd());
//                                ordine.setCodMdep(data.getCodMdep());
//                                ordine.setNumOrd(data.getNumOrd());
                                onSuccess.run(ordine);
                            }, false);
                        }, onFailed);
                    }

                    @Override
                    public void onFailure(Call<ServiceRESTResponse<Object>> call, Throwable t) {
                        Log.e("saveOrdine", t.toString());
                        UtilityLogger.error(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.setDataIns(art.getDataIns());
        dto.setUntMis(art.getUntMis());
        dto.setSystemNote(art.getSystemNote());
        dto.setQta(BigDecimal.valueOf(art.getQtaOrd()));
        dto.setQtaCnf(BigDecimal.valueOf(art.getQtaCnf()));
        dto.setCodAlis(art.getCodAlis());
        dto.setColli(BigDecimal.ZERO);
        return dto;
    }

}
