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

import java.math.BigDecimal;

import javax.inject.Singleton;

import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.model.MtbAart;
import it.integry.integrywmsnative.core.model.MtbColr;
import it.integry.integrywmsnative.core.model.MtbColt;
import it.integry.integrywmsnative.core.model.MtbDepoPosizione;
import it.integry.integrywmsnative.core.rest.RESTBuilder;
import it.integry.integrywmsnative.core.rest.consumers.interfaces.ColliCaricoRESTConsumerInterface;
import it.integry.integrywmsnative.core.rest.consumers.interfaces.ColliScaricoRESTConsumerInterface;
import it.integry.integrywmsnative.core.rest.model.ServiceRESTResponse;
import it.integry.integrywmsnative.core.rest.model.udc.CloseUDCRequestDTO;
import it.integry.integrywmsnative.core.rest.model.udc.CloseUDCResponseDTO;
import it.integry.integrywmsnative.core.rest.model.udc.CreateUDCRequestDTO;
import it.integry.integrywmsnative.core.rest.model.udc.CreateUDCResponseDTO;
import it.integry.integrywmsnative.core.rest.model.udc.DeleteUDCRowRequestDTO;
import it.integry.integrywmsnative.core.rest.model.udc.EditUDCRowRequestDTO;
import it.integry.integrywmsnative.core.rest.model.udc.EditUDCRowResponseDTO;
import it.integry.integrywmsnative.core.rest.model.uds.CloseUDSRequestDTO;
import it.integry.integrywmsnative.core.rest.model.uds.CloseUDSResponseDTO;
import it.integry.integrywmsnative.core.rest.model.uds.CreateUDSFromArtRequestDTO;
import it.integry.integrywmsnative.core.rest.model.uds.CreateUDSRequestDTO;
import it.integry.integrywmsnative.core.rest.model.uds.CreateUDSResponseDTO;
import it.integry.integrywmsnative.core.rest.model.uds.DeleteUDSRowRequestDTO;
import it.integry.integrywmsnative.core.rest.model.uds.EditUDSRowRequestDTO;
import it.integry.integrywmsnative.core.rest.model.uds.EditUDSRowResponseDTO;
import it.integry.integrywmsnative.core.rest.model.uds.InsertUDCRowRequestDTO;
import it.integry.integrywmsnative.core.rest.model.uds.InsertUDCRowResponseDTO;
import it.integry.integrywmsnative.core.rest.model.uds.InsertUDSRowRequestDTO;
import it.integry.integrywmsnative.core.rest.model.uds.InsertUDSRowResponseDTO;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

@Singleton
public class ColliLavorazioneRESTConsumer extends _BaseRESTConsumer implements ColliCaricoRESTConsumerInterface, ColliScaricoRESTConsumerInterface {


    private final SettingsManager settingsManager;

    public ColliLavorazioneRESTConsumer(SettingsManager settingsManager) {
        this.settingsManager = settingsManager;
    }

    @Override
    public void createUDC(CreateUDCRequestDTO createUDCRequestDTO, RunnableArgs<MtbColt> onComplete, RunnableArgs<Exception> onFailed) {
        ColliLavorazioneRESTConsumerService colliLavorazioneRESTConsumerService = RESTBuilder.getService(ColliLavorazioneRESTConsumerService.class);

        colliLavorazioneRESTConsumerService.createUDC(createUDCRequestDTO)
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<CreateUDCResponseDTO>> call, Response<ServiceRESTResponse<CreateUDCResponseDTO>> response) {
                        analyzeAnswer(response, "lavorazione/createUDC", data -> onComplete.run(data.getMtbColt()), onFailed);
                    }

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

    @Override
    public void closeUDC(CloseUDCRequestDTO closeUDCRequestDTO, RunnableArgs<CloseUDCResponseDTO> onComplete, RunnableArgs<Exception> onFailed) {
        ColliLavorazioneRESTConsumerService colliLavorazioneRESTConsumerService = RESTBuilder.getService(ColliLavorazioneRESTConsumerService.class);

        colliLavorazioneRESTConsumerService.closeUDC(closeUDCRequestDTO)
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<CloseUDCResponseDTO>> call, Response<ServiceRESTResponse<CloseUDCResponseDTO>> response) {
                        analyzeAnswer(response, "lavorazione/closeUDC", onComplete, onFailed);
                    }

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

    @Override
    public void insertUDCRow(InsertUDCRowRequestDTO insertUDCRowRequestDTO, RunnableArgs<MtbColr> onComplete, RunnableArgs<Exception> onFailed) {
        ColliLavorazioneRESTConsumerService colliLavorazioneRESTConsumerService = RESTBuilder.getService(ColliLavorazioneRESTConsumerService.class);

        colliLavorazioneRESTConsumerService.insertUDCRow(insertUDCRowRequestDTO)
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<InsertUDCRowResponseDTO>> call, Response<ServiceRESTResponse<InsertUDCRowResponseDTO>> response) {
                        analyzeAnswer(response, "lavorazione/insertUDCRow", data -> onComplete.run(data.getSavedMtbColr()), onFailed);
                    }

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

    @Override
    public void editUDCRow(EditUDCRowRequestDTO editUDCRowRequestDTO, RunnableArgs<MtbColr> onComplete, RunnableArgs<Exception> onFailed) {
        ColliLavorazioneRESTConsumerService colliLavorazioneRESTConsumerService = RESTBuilder.getService(ColliLavorazioneRESTConsumerService.class);

        colliLavorazioneRESTConsumerService.editUDCRow(editUDCRowRequestDTO)
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<EditUDCRowResponseDTO>> call, Response<ServiceRESTResponse<EditUDCRowResponseDTO>> response) {
                        analyzeAnswer(response, "lavorazione/editUDCRow", data -> onComplete.run(data.getSavedMtbColr()), onFailed);
                    }

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

    public void createUDS(CreateUDSRequestDTO createUDSRequestDTO, RunnableArgs<MtbColt> onComplete, RunnableArgs<Exception> onFailed) {
        ColliLavorazioneRESTConsumerService colliLavorazioneRESTConsumerService = RESTBuilder.getService(ColliLavorazioneRESTConsumerService.class);

        colliLavorazioneRESTConsumerService.createUDS(createUDSRequestDTO)
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<CreateUDSResponseDTO>> call, Response<ServiceRESTResponse<CreateUDSResponseDTO>> response) {
                        analyzeAnswer(response, "lavorazione/createUDS", data -> onComplete.run(data.getMtbColt()), onFailed);
                    }

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

    }

    @Override
    public void closeUDS(CloseUDSRequestDTO closeUDSRequestDTO, RunnableArgs<CloseUDSResponseDTO> onComplete, RunnableArgs<Exception> onFailed) {
        ColliLavorazioneRESTConsumerService colliLavorazioneRESTConsumerService = RESTBuilder.getService(ColliLavorazioneRESTConsumerService.class);

        colliLavorazioneRESTConsumerService.closeUDS(closeUDSRequestDTO)
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<CloseUDSResponseDTO>> call, Response<ServiceRESTResponse<CloseUDSResponseDTO>> response) {
                        analyzeAnswer(response, "lavorazione/closeUDS", onComplete, onFailed);
                    }

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

    @Override
    public void insertUDSRow(InsertUDSRowRequestDTO insertUDSRowRequestDTO, RunnableArgs<MtbColr> onComplete, RunnableArgs<Exception> onFailed) {
        ColliLavorazioneRESTConsumerService colliLavorazioneRESTConsumerService = RESTBuilder.getService(ColliLavorazioneRESTConsumerService.class);

        colliLavorazioneRESTConsumerService.insertUDSRow(insertUDSRowRequestDTO)
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<InsertUDSRowResponseDTO>> call, Response<ServiceRESTResponse<InsertUDSRowResponseDTO>> response) {
                        analyzeAnswer(response, "lavorazione/insertUDSRow", data -> onComplete.run(data.getSavedMtbColr()), onFailed);
                    }

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

    public void editUDSRow(EditUDSRowRequestDTO editUDSRowRequestDTO, RunnableArgs<MtbColr> onComplete, RunnableArgs<Exception> onFailed) {
        ColliLavorazioneRESTConsumerService colliLavorazioneRESTConsumerService = RESTBuilder.getService(ColliLavorazioneRESTConsumerService.class);

        colliLavorazioneRESTConsumerService.editUDSRow(editUDSRowRequestDTO)
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<EditUDSRowResponseDTO>> call, Response<ServiceRESTResponse<EditUDSRowResponseDTO>> response) {
                        analyzeAnswer(response, "lavorazione/editUDSRow", data -> onComplete.run(data.getSavedMtbColr()), onFailed);
                    }

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

    @Override
    public void deleteUDSRow(DeleteUDSRowRequestDTO deleteUDSRowRequestDTO, Runnable onComplete, RunnableArgs<Exception> onFailed) {
        ColliLavorazioneRESTConsumerService colliLavorazioneRESTConsumerService = RESTBuilder.getService(ColliLavorazioneRESTConsumerService.class);

        colliLavorazioneRESTConsumerService.deleteUDSRow(deleteUDSRowRequestDTO)
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<Void>> call, Response<ServiceRESTResponse<Void>> response) {
                        analyzeAnswer(response, "lavorazione/deleteUDSRow", data -> onComplete.run(), onFailed);
                    }

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

    @Override
    public void deleteUDCRow(DeleteUDCRowRequestDTO deleteUDCRowRequestDTO, Runnable onComplete, RunnableArgs<Exception> onFailed) {
        ColliLavorazioneRESTConsumerService colliLavorazioneRESTConsumerService = RESTBuilder.getService(ColliLavorazioneRESTConsumerService.class);

        colliLavorazioneRESTConsumerService.deleteUDCRow(deleteUDCRowRequestDTO)
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<Void>> call, Response<ServiceRESTResponse<Void>> response) {
                        analyzeAnswer(response, "lavorazione/deleteUDCRow", data -> onComplete.run(), onFailed);
                    }

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


    public void createColloScaricoDaArticolo(MtbAart mtbAart,
                                             String partitaMag,
                                             MtbDepoPosizione posizione,
                                             BigDecimal qta, BigDecimal qtaCnf, BigDecimal numCnf,
                                             BigDecimal pesoNettoKg, BigDecimal pesoLordoKg,
                                             Runnable onComplete, RunnableArgs<Exception> onFailed) {

        CreateUDSFromArtRequestDTO createUDSFromArtRequestDTO = new CreateUDSFromArtRequestDTO()
                .setCodMart(mtbAart.getCodMart())
                .setCodMdep(settingsManager.getSettings().getUserSession().getDepo().getCodMdep())
                .setPartitaMag(partitaMag)
                .setPosizione(posizione != null ? posizione.getPosizione() : null)
                .setQta(qta)
                .setQtaCnf(qtaCnf)
                .setNumCnf(numCnf)
                .setPesoLordoKg(pesoLordoKg)
                .setPesoNettoKg(pesoNettoKg);

        if (posizione != null && posizione.isFlagLineaProduzione()) {
            createUDSFromArtRequestDTO
                    .setCodJfas(posizione.getPosizione());
        }
        ColliLavorazioneRESTConsumerService colliLavorazioneRESTConsumerService = RESTBuilder.getService(ColliLavorazioneRESTConsumerService.class);

        colliLavorazioneRESTConsumerService.createUDSFromArt(createUDSFromArtRequestDTO)
                .enqueue(new Callback<>() {
                    @Override
                    public void onResponse(Call<ServiceRESTResponse<Void>> call, Response<ServiceRESTResponse<Void>> response) {
                        analyzeAnswer(response, "lavorazione/createUDSFromArt", data -> onComplete.run(), onFailed);
                    }

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