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

import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.text.SpannableString;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;

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.core.utility.UtilityExceptions;
import it.integry.integrywmsnative.databinding.DialogScanOrCreateLuBinding;
import it.integry.integrywmsnative.view.dialogs.base.DialogSimpleMessageView;
import it.integry.integrywmsnative.view.dialogs.basket_lu.DialogBasketLU;

public class DialogScanOrCreateLUView extends BaseDialogFragment implements DialogScanOrCreateLUViewModel.Listener {

    @Inject
    DialogScanOrCreateLUViewModel mViewModel;

    private DialogScanOrCreateLuBinding mBindings;
    private int mBarcodeScannerIstanceID;

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

    private boolean mShouldCheckResiduo;
    private boolean mShouldCheckIfExistDoc;
    private boolean mEnableCreation;

    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, onComplete);
    }

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

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

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

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

        mEnableCreation = enableCreation;
        mOnComplete = onComplete;
    }


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        this.initBarcode();

        mBindings = DataBindingUtil.inflate(inflater, R.layout.dialog_scan_or_create_lu, container, false);
        mBindings.setLifecycleOwner(this);
        mBindings.setView(this);

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

        this.mViewModel
                .setListener(this);

        getDialog().setCanceledOnTouchOutside(false);
        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

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

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

        mBindings.viewBasket.setOnClickListener(v -> {
            DialogBasketLU.make(getActivity(), mtbColt -> {
                onLUOpened(mtbColt, false);
            }).show();
        });

        return mBindings.getRoot();
    }


    @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()
                .setOnScanSuccessfull(onScanSuccessfull)
                .setOnScanFailed(this::onError));

        setBarcodeListener(true);
    }

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

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


    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(((AppCompatActivity) getActivity()).getSupportFragmentManager(), "tag");
    }

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

    @Override
    public void onError(Exception ex) {
        this.closeProgress();
        UtilityExceptions.defaultException(getActivity(), ex);
        BarcodeManager.enable();
    }

    @Override
    public void onLoadingStarted() {
        this.openProgress();
    }

    @Override
    public void onLoadingEnded() {
        this.closeProgress();
    }

}
