package it.integry.integrywmsnative.view.dialogs.scan_or_create_lu;

import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.SpannableString;
import android.view.LayoutInflater;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.google.android.material.dialog.MaterialAlertDialogBuilder;

import org.jetbrains.annotations.NotNull;

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.di.BindableBoolean;
import it.integry.integrywmsnative.core.expansion.BaseDialogFragment;
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.expansion.RunnableArgss;
import it.integry.integrywmsnative.core.model.MtbColt;
import it.integry.integrywmsnative.databinding.DialogScanOrCreateLuBinding;
import it.integry.integrywmsnative.view.dialogs.base.DialogSimpleMessageView;
import it.integry.integrywmsnative.view.dialogs.basket_lu.DialogBasketLUView;

public class DialogScanOrCreateLUView extends BaseDialogFragment implements DialogScanOrCreateLUViewModel.Listener {

    @Inject
    DialogScanOrCreateLUViewModel mViewModel;

    private DialogScanOrCreateLuBinding mBindings;
    private int mBarcodeScannerIstanceID;

    private final RunnableArgss<MtbColt, Boolean> mOnComplete;
    private MtbColt openedMtbColt;

    private final boolean mShouldCheckResiduo;
    private final boolean mShouldCheckIfExistDoc;
    private final boolean mEnableCreation;
    private final boolean mWarnOnOpeningVendita;

    private final BindableBoolean basketEnabled = new BindableBoolean();
    private final BindableBoolean creationEnabled = new BindableBoolean();


    public static DialogScanOrCreateLUView newInstance(@NotNull RunnableArgss<MtbColt, Boolean> onComplete) {
        return new DialogScanOrCreateLUView(false, true, true, true, true, onComplete);
    }

    public static DialogScanOrCreateLUView newInstance(boolean enableCreation, boolean shouldCheckIfExistDoc, boolean warnOnOpeningVendita, @NotNull RunnableArgss<MtbColt, Boolean> onComplete) {
        return new DialogScanOrCreateLUView(false, enableCreation, true, shouldCheckIfExistDoc, warnOnOpeningVendita, onComplete);
    }

    public static DialogScanOrCreateLUView newInstance(boolean enableBasket, boolean enableCreation, boolean checkResiduo, boolean shouldCheckIfExistDoc, boolean warnOnOpeningVendita, @NotNull RunnableArgss<MtbColt, Boolean> onComplete) {
        return new DialogScanOrCreateLUView(enableBasket, enableCreation, checkResiduo, shouldCheckIfExistDoc, warnOnOpeningVendita, onComplete);
    }

    private DialogScanOrCreateLUView(boolean enableBasket, boolean enableCreation, boolean checkResiduo, boolean shouldCheckIfExistDoc, boolean warnOnOpeningVendita, @NotNull RunnableArgss<MtbColt, Boolean> onComplete) {
        super();
        mShouldCheckResiduo = checkResiduo;
        mShouldCheckIfExistDoc = shouldCheckIfExistDoc;
        mWarnOnOpeningVendita = warnOnOpeningVendita;

        this.basketEnabled.set(enableBasket);
        this.creationEnabled.set(enableCreation);

        mEnableCreation = enableCreation;
        mOnComplete = onComplete;

        MainApplication.appComponent
                .dialogScanOrCreateLUComponent()
                .create()
                .inject(this);
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        this.initBarcode();

        mBindings = DialogScanOrCreateLuBinding.inflate(LayoutInflater.from(requireContext()), null, false);
        mBindings.setLifecycleOwner(this);
        mBindings.setView(this);

        this.mViewModel
                .setListener(this);


        this.mViewModel.init(mShouldCheckResiduo, mShouldCheckIfExistDoc, mEnableCreation, mWarnOnOpeningVendita);

        mBindings.createNewLuButton.setOnClickListener(v -> {
            this.mViewModel.createNewLU();
//            dismiss();
        });

        mBindings.viewBasket.setOnClickListener(v -> {
            new DialogBasketLUView(mtbColt -> {
                onLUOpened(mtbColt, false);
            }).show(requireActivity().getSupportFragmentManager(), "tag");
        });

        var alertDialog = new MaterialAlertDialogBuilder(requireContext())
                .setView(mBindings.getRoot())
                .setCancelable(false)
                .create();
        alertDialog.setCanceledOnTouchOutside(false);
        alertDialog.setOnShowListener(this);
        return alertDialog;
    }

    @Override
    public void onDismiss(@NonNull DialogInterface dialog) {
        BarcodeManager.removeCallback(mBarcodeScannerIstanceID);
        BarcodeManager.enable();
        if (openedMtbColt == null) {
            mOnComplete.run(null, false);
        }
        super.onDismiss(dialog);
    }


    private void initBarcode() {
        mBarcodeScannerIstanceID = BarcodeManager.addCallback(new BarcodeCallbackDTO()
                .setOnScanSuccessful(onScanSuccessfull)
                .setOnScanFailed(this::onError));
        BarcodeManager.enable();
        setBarcodeListener(true);
    }

    private final RunnableArgs<BarcodeScanDTO> onScanSuccessfull = data -> {
        this.onLoadingStarted();

        this.mViewModel.processBarcodeDTO(data, () -> {
            this.onLoadingEnded();
        });
    };


    public BindableBoolean getBasketEnabled() {
        return basketEnabled;
    }

    public BindableBoolean getCreationEnabled() {
        return creationEnabled;
    }

    @Override
    public void onLUVenditaConfirmRequired(RunnableArgs<Boolean> onConfirm) {
        DialogSimpleMessageView.makeWarningDialog(new SpannableString(getString(R.string.lu_gest_v_loading_alert)),
                        null, () -> {
                            onConfirm.run(true);
                        }, () -> {
                            onConfirm.run(false);
                        })
                .show(requireActivity().getSupportFragmentManager(), "tag");
    }

    @Override
    public void onLUOpened(MtbColt mtbColt, boolean created) {
        this.openedMtbColt = mtbColt;
        mOnComplete.run(mtbColt, created);
        dismiss();
    }

}
