package it.integry.integrywmsnative.gest.versamento_merce;

import android.content.Context;
import android.os.Bundle;
import android.text.Html;
import android.text.SpannableString;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.appcompat.widget.AppCompatTextView;
import androidx.databinding.DataBindingUtil;

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

import javax.inject.Inject;

import it.integry.barcode_base_android_library.model.BarcodeScanDTO;
import it.integry.integrywmsnative.MainApplication;
import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.barcode_reader.BarcodeCallbackDTO;
import it.integry.integrywmsnative.core.barcode_reader.BarcodeManager;
import it.integry.integrywmsnative.core.expansion.BaseFragment;
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.interfaces.IPoppableActivity;
import it.integry.integrywmsnative.core.interfaces.ITitledFragment;
import it.integry.integrywmsnative.core.model.MtbAart;
import it.integry.integrywmsnative.core.model.MtbColr;
import it.integry.integrywmsnative.core.model.MtbDepoPosizione;
import it.integry.integrywmsnative.core.model.secondary.GestioneEnum;
import it.integry.integrywmsnative.core.utility.UtilityExceptions;
import it.integry.integrywmsnative.databinding.FragmentMainVersamentoMerceBinding;
import it.integry.integrywmsnative.gest.spedizione.model.PickedQuantityDTO;
import it.integry.integrywmsnative.view.dialogs.DialogAskLivelloPosizione;
import it.integry.integrywmsnative.view.dialogs.DialogCommon;
import it.integry.integrywmsnative.view.dialogs.base.DialogSimpleMessageView;
import it.integry.integrywmsnative.view.dialogs.choose_arts_from_lista_arts.DialogChooseArtsFromListaArts;
import it.integry.integrywmsnative.view.dialogs.input_quantity_v2.DialogInputQuantityV2DTO;
import it.integry.integrywmsnative.view.dialogs.input_quantity_v2.DialogInputQuantityV2View;
import it.integry.integrywmsnative.view.dialogs.scan_or_create_lu.DialogScanOrCreateLUView;

public class VersamentoMerceFragment extends BaseFragment implements ITitledFragment, VersamentoMerceViewModel.Listener {


    @Inject
    VersamentoMerceViewModel mViewModel;

    private FragmentMainVersamentoMerceBinding mBindings = null;

    private final List<Runnable> mOnPreDestroyList = new ArrayList<>();

    private int barcodeScannerIstanceID = -1;


    public static VersamentoMerceFragment newInstance() {
        return new VersamentoMerceFragment();
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        mBindings = DataBindingUtil.inflate(inflater, R.layout.fragment_main_versamento_merce, container, false);

        MainApplication.appComponent
                .versamentoMerceComponent()
                .create()
                .inject(this);

        mViewModel.setListener(this);

        mBindings.setLifecycleOwner(this);
        mBindings.setView(this);
        mBindings.setViewmodel(mViewModel);

        this.initBarcodeReader();

        this.openLU();

        return mBindings.getRoot();
    }

    @Override
    public void onDestroy() {
        BarcodeManager.removeCallback(barcodeScannerIstanceID);

        for (Runnable onPreDestroy : mOnPreDestroyList) {
            onPreDestroy.run();
        }
        super.onDestroy();
    }


    public void openLU() {
        DialogScanOrCreateLUView.newInstance(true, false, true, false, (mtbColt, created) -> {
            if (mtbColt == null) {
                ((IPoppableActivity) getActivity()).pop();
            } else if ((mtbColt.getGestioneEnum() == GestioneEnum.ACQUISTO || mtbColt.getGestioneEnum() == GestioneEnum.LAVORAZIONE) && mtbColt.getSegno().equals(+1)) {
                this.mViewModel.getCurrentMtbColt().postValue(mtbColt);
            } else if (mtbColt.getGestioneEnum() == GestioneEnum.VENDITA) {
                this.mViewModel.getCurrentMtbColt().postValue(mtbColt);
            } else {
                DialogSimpleMessageView
                        .makeWarningDialog(new SpannableString(Html.fromHtml("Sono accettate solamente UL di <b>Acquisto</b> o <b>Lavorazione</b> di <b>CARICO</b>")),
                                null, this::openLU)
                        .show(getActivity().getSupportFragmentManager(), "tag");
            }
        }).show(getActivity().getSupportFragmentManager(), "tag");
    }


    private void initBarcodeReader() {
        barcodeScannerIstanceID = BarcodeManager.addCallback(new BarcodeCallbackDTO()
                .setOnScanSuccessfull(onScanSuccessful)
                .setOnScanFailed(ex -> UtilityExceptions.defaultException(getActivity(), ex, false)));

        BarcodeManager.enable();
    }

    private final RunnableArgs<BarcodeScanDTO> onScanSuccessful = data -> {
        BarcodeManager.disable();
        this.openProgress();

        this.mViewModel.processBarcodeDTO(data, () -> {
            BarcodeManager.enable();
            this.closeProgress();
        });
    };


    @Override
    public void onCreateActionBar(AppCompatTextView titleText, Context context) {
        titleText.setText(context.getText(R.string.versamento_merce_fragment_title).toString());
    }

    @Override
    public void addOnPreDestroy(Runnable onPreDestroy) {
        this.mOnPreDestroyList.add(onPreDestroy);
    }


    @Override
    public void onLivelloPosizioneRequired(MtbDepoPosizione posizione, RunnableArgs<MtbDepoPosizione> onComplete) {
        this.getActivity().runOnUiThread(() -> {
            DialogAskLivelloPosizione.make(getActivity(), posizione, false, onComplete, this::onError);
        });
    }

    @Override
    public void onSpostamentoTraDepConfirmRequired(String sourceCodMdep, String destinationCodMdep, RunnableArgs<Boolean> onComplete) {
        this.getActivity().runOnUiThread(() -> {
            DialogSimpleMessageView.makeWarningDialog(Html.fromHtml("Stai spostando una UL dal deposito <b>" + sourceCodMdep + "</b> al deposito <b>" + destinationCodMdep + "</b>"),
                    null,
                    () -> onComplete.run(true),
                    () -> onComplete.run(false))
                    .show(getActivity().getSupportFragmentManager(), "tag");
        });
    }

    @Override
    public void onArtsChooseRequired(List<MtbColr> mtbColrList, RunnableArgs<List<MtbColr>> onComplete, Runnable onAbort) {
        this.requireActivity().runOnUiThread(() -> {
            DialogChooseArtsFromListaArts
                    .newInstance(mtbColrList, onComplete, onAbort)
                    .show(requireActivity().getSupportFragmentManager(), "tag");
        });
    }

    @Override
    public void onItemDispatched(MtbAart mtbAart,
                                 BigDecimal initialNumCnf,
                                 BigDecimal initialQtaCnf,
                                 BigDecimal initialQtaTot,
                                 BigDecimal totalQtaAvailable,
                                 BigDecimal totalNumCnfAvailable,
                                 BigDecimal qtaCnfAvailable,
                                 String partitaMag,
                                 Date dataScad,
                                 boolean canOverflowOrderQuantity,
                                 boolean canBatchLotBeChanged,
                                 RunnableArgs<PickedQuantityDTO> onComplete) {
        DialogInputQuantityV2DTO dialogInputQuantityV2DTO = new DialogInputQuantityV2DTO()
                .setMtbAart(mtbAart)
                .setInitialNumCnf(initialNumCnf)
                .setInitialQtaCnf(initialQtaCnf)
                .setInitialQtaTot(initialQtaTot)
                .setTotalQtaAvailable(totalQtaAvailable)
                .setTotalNumCnfAvailable(totalNumCnfAvailable)
                .setQtaCnfAvailable(qtaCnfAvailable)
                .setPartitaMag(partitaMag)
                .setDataScad(dataScad)
                .setCanOverflowOrderQuantity(canOverflowOrderQuantity)
                .setCanPartitaMagBeChanged(canBatchLotBeChanged)
                .setCanLUBeClosed(false);

        this.getActivity().runOnUiThread(() -> {
            DialogInputQuantityV2View
                    .newInstance(dialogInputQuantityV2DTO, (resultDTO, shouldCloseLU) -> {

                        PickedQuantityDTO pickedQuantityDTO = new PickedQuantityDTO()
                                .setNumCnf(resultDTO.getNumCnf())
                                .setQtaCnf(resultDTO.getQtaCnf())
                                .setQtaTot(resultDTO.getQtaTot())
                                .setPartitaMag(resultDTO.getPartitaMag())
                                .setDataScad(resultDTO.getDataScad());

                        onComplete.run(pickedQuantityDTO);

                    }, this::onLoadingEnded)
                    .show(getActivity().getSupportFragmentManager(), "tag");
        });
    }

    @Override
    public void onDataSaved() {
        this.requireActivity().runOnUiThread(() -> {
            DialogCommon.showDataSaved(requireActivity(), this::popMe);
        });
    }
}
