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

import android.content.Context;
import android.content.DialogInterface;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.text.Html;
import android.text.InputType;
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.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ObservableField;
import androidx.fragment.app.DialogFragment;

import com.google.android.material.textfield.TextInputLayout;
import com.pedromassango.doubleclick.DoubleClick;
import com.pedromassango.doubleclick.DoubleClickListener;

import org.jetbrains.annotations.NotNull;

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

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.BaseDialogFragment;
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.expansion.RunnableArgss;
import it.integry.integrywmsnative.core.model.MtbUntMis;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import it.integry.integrywmsnative.core.utility.UtilityExceptions;
import it.integry.integrywmsnative.core.utility.UtilityObservable;
import it.integry.integrywmsnative.databinding.DialogInputQuantityV2Binding;
import it.integry.integrywmsnative.view.dialogs.base.DialogSimpleMessageView;

public class DialogInputQuantityV2View extends BaseDialogFragment implements DialogInputQuantityV2ViewModel.Listener {

    @Inject
    DialogInputQuantityV2ViewModel mViewModel;

    private DialogInputQuantityV2DTO mDialogInputQuantityV2DTO;
    private RunnableArgss<DialogInputQuantityV2ResultDTO, Boolean> mOnComplete;
    private Runnable mOnAbort;

    public ObservableField<String> currentPartitaMag = new ObservableField<>();
    public ObservableField<Date> currentDataScad = new ObservableField<>();

    public ObservableField<BigDecimal> currentNumCnf = new ObservableField<>();
    public ObservableField<BigDecimal> currentQtaCnf = new ObservableField<>();
    public ObservableField<BigDecimal> currentQtaTot = new ObservableField<>();

    public ObservableField<Boolean> enabledNumCnf = new ObservableField<>(true);
    public ObservableField<Boolean> enabledQtaCnf = new ObservableField<>(true);
    public ObservableField<Boolean> enabledQtaTot = new ObservableField<>(true);

    public ObservableField<Boolean> enabledChangePartitaMag = new ObservableField<>(true);
    public ObservableField<Boolean> enabledLUCloseButton = new ObservableField<>(true);

    private Context context;

    private DialogInputQuantityV2Binding mBindings;
    private boolean mEnableDataCallback = true;

    private int mBarcodeScannerIstanceID;

    public static DialogInputQuantityV2View newInstance(@NotNull DialogInputQuantityV2DTO dialogInputQuantityV2DTO, @NotNull RunnableArgss<DialogInputQuantityV2ResultDTO, Boolean> onComplete, @NotNull Runnable onAbort) {
        return new DialogInputQuantityV2View(dialogInputQuantityV2DTO, onComplete, onAbort);
    }

    private DialogInputQuantityV2View(@NotNull DialogInputQuantityV2DTO dialogInputQuantityV2DTO, @NotNull RunnableArgss<DialogInputQuantityV2ResultDTO, Boolean> onComplete, @NotNull Runnable onAbort) {
        super();

        this.mDialogInputQuantityV2DTO = dialogInputQuantityV2DTO;
        this.mOnComplete = onComplete;
        this.mOnAbort = onAbort;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NORMAL, R.style.AppTheme_NewMaterial_Dialog_FullscreenDialog);

        this.initBarcode();
    }

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

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

        mBindings.toolbar.setTitle("Inserimento articolo");

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

        this.mViewModel
                .setMtbAart(mDialogInputQuantityV2DTO.getMtbAart())
                .setInitialNumCnf(mDialogInputQuantityV2DTO.getInitialNumCnf())
                .setInitialQtaCnf(mDialogInputQuantityV2DTO.getInitialQtaCnf())
                .setInitialQtaTot(mDialogInputQuantityV2DTO.getInitialQtaTot())
                .setTotalNumCnfOrd(mDialogInputQuantityV2DTO.getTotalNumCnfOrd())
                .setTotalQtaOrd(mDialogInputQuantityV2DTO.getTotalQtaOrd())
                .setQtaCnfOrd(mDialogInputQuantityV2DTO.getQtaCnfOrd())
                .setTotalNumCnfToBeTaken(mDialogInputQuantityV2DTO.getTotalNumCnfToBeTaken())
                .setTotalQtaToBeTaken(mDialogInputQuantityV2DTO.getTotalQtaToBeTaken())
                .setQtaCnfToBeTaken(mDialogInputQuantityV2DTO.getQtaCnfToBeTaken())
                .setTotalNumCnfAvailable(mDialogInputQuantityV2DTO.getTotalNumCnfAvailable())
                .setTotalQtaAvailable(mDialogInputQuantityV2DTO.getTotalQtaAvailable())
                .setCanOverflowOrderQuantity(mDialogInputQuantityV2DTO.isCanOverflowOrderQuantity())
                .setQtaCnfAvailable(mDialogInputQuantityV2DTO.getQtaCnfAvailable())
                .setPartitaMag(mDialogInputQuantityV2DTO.getPartitaMag())
                .setDataScad(mDialogInputQuantityV2DTO.getDataScad());

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

        MtbUntMis mtbUntMis = mDialogInputQuantityV2DTO.getMtbAart().getMtbUntMis() != null && mDialogInputQuantityV2DTO.getMtbAart().getMtbUntMis().size() > 0 ? mDialogInputQuantityV2DTO.getMtbAart().getMtbUntMis().get(0) : null;
        if (!(mtbUntMis != null && mtbUntMis.isFlagDig())) {
            mBindings.inputQtaTotText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
        }

        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        return mBindings.getRoot();
    }

    private void initBarcode() {
        mBarcodeScannerIstanceID = BarcodeManager.addCallback(new BarcodeCallbackDTO()
                .setOnScanSuccessfull(onScanSuccessful)
                .setOnScanFailed(ex -> UtilityExceptions.defaultException(this.context, ex, false)));
    }

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

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

    public void save() {
        if (this.mViewModel.validate()) {
            this.mOnComplete.run(this.mViewModel.getResult(), false);
            dismiss();
        }
    }

    public void saveAndCloseLU() {
        if (this.mViewModel.validate()) {
            this.mOnComplete.run(this.mViewModel.getResult(), true);
            dismiss();
        }
    }

    @Override
    public void onDismiss(@NonNull DialogInterface dialog) {
        BarcodeManager.removeCallback(mBarcodeScannerIstanceID);
        this.mOnAbort.run();
        super.onDismiss(dialog);
    }

    @Override
    public void onStart() {
        super.onStart();
        this.init();

        int onNumCnfInputChanged = SettingsManager.iDB().getOnNumCnfInputChanged();

        this.mViewModel.setListener(this);
        this.mViewModel.init(onNumCnfInputChanged);
    }

    private void init() {
        UtilityObservable.addPropertyChanged(this.currentPartitaMag, (value) -> {
            if (this.mEnableDataCallback) {
                this.mViewModel.setPartitaMag(value);
            }
        });

        UtilityObservable.addPropertyChanged(this.currentDataScad, (value) -> {
            if (this.mEnableDataCallback) {
                this.mViewModel.setDataScad(value);
            }
        });

        UtilityObservable.addPropertyChanged(this.currentNumCnf, (value) -> {
            if (this.mEnableDataCallback) {
                this.mViewModel.setNumCnf(value);
            }
        });

        UtilityObservable.addPropertyChanged(this.currentQtaCnf, (value) -> {
            if (this.mEnableDataCallback) {
                this.mViewModel.setQtaCnf(value);
            }
        });

        UtilityObservable.addPropertyChanged(this.currentQtaTot, (value) -> {
            if (this.mEnableDataCallback) {
                this.mViewModel.setQtaTot(value);
            }
        });

        final ColorStateList textColorsNumCnf = this.mBindings.inputNumCnfLayout.getEditText().getTextColors();
        final ColorStateList textColorsQtaCnf = this.mBindings.inputQtaCnfLayout.getEditText().getTextColors();
        final ColorStateList textColorsQtaTot = this.mBindings.inputQtaTotLayout.getEditText().getTextColors();

        UtilityObservable.addPropertyChanged(this.mViewModel.blockedNumCnf, (value) -> {
            toggleTextInputLayoutError(textColorsNumCnf, this.mBindings.inputNumCnfLayout, value);

            if (this.mViewModel.mtbAart.get().isFlagQtaCnfFissaBoolean()) {
                this.enabledQtaTot.set(!value);
            } else {
                if (value) {
                    if (this.mViewModel.blockedQtaCnf.get()) {
                        this.enabledQtaTot.set(false);
                    } else if (this.mViewModel.blockedQtaTot.get()) {
                        this.enabledQtaCnf.set(false);
                    }
                } else {
                    if (!this.enabledQtaTot.get()) {
                        this.enabledQtaTot.set(true);
                    } else if (!this.enabledQtaCnf.get()) {
                        this.enabledQtaCnf.set(true);
                    }
                }
            }
        });

        UtilityObservable.addPropertyChanged(this.mViewModel.blockedQtaCnf, (value) -> {
            toggleTextInputLayoutError(textColorsQtaCnf, this.mBindings.inputQtaCnfLayout, value);

            if (value) {
                if (this.mViewModel.blockedNumCnf.get()) {
                    this.enabledQtaTot.set(false);
                } else if (this.mViewModel.blockedQtaTot.get()) {
                    this.enabledNumCnf.set(false);
                }
            } else {
                if (!this.enabledQtaTot.get()) {
                    this.enabledQtaTot.set(true);
                } else if (!this.enabledNumCnf.get()) {
                    this.enabledNumCnf.set(true);
                }
            }
        });

        UtilityObservable.addPropertyChanged(this.mViewModel.blockedQtaTot, (value) -> {
            toggleTextInputLayoutError(textColorsQtaTot, this.mBindings.inputQtaTotLayout, value);

            if (this.mViewModel.mtbAart.get().isFlagQtaCnfFissaBoolean()) {
                this.enabledNumCnf.set(!value);
            } else {
                if (value) {
                    if (this.mViewModel.blockedQtaCnf.get()) {
                        this.enabledNumCnf.set(false);
                    } else if (this.mViewModel.blockedNumCnf.get()) {
                        this.enabledQtaCnf.set(false);
                    }
                } else {
                    if (!this.enabledQtaCnf.get()) {
                        this.enabledQtaCnf.set(true);
                    } else if (!this.enabledNumCnf.get()) {
                        this.enabledNumCnf.set(true);
                    }
                }
            }
        });

        //Init double taps
        this.mBindings.inputNumCnfText.setOnClickListener(new DoubleClick(new DoubleClickListener() {
            @Override
            public void onSingleClick(View view) {
                String a = "";
            }

            @Override
            public void onDoubleClick(View view) {
                mViewModel.blockedNumCnf.set(!mViewModel.blockedNumCnf.get());
            }
        }));

        this.mBindings.inputQtaCnfText.setOnClickListener(new DoubleClick(new DoubleClickListener() {
            @Override
            public void onSingleClick(View view) {
                String a = "";
            }

            @Override
            public void onDoubleClick(View view) {
                mViewModel.blockedQtaCnf.set(!mViewModel.blockedQtaCnf.get());
            }
        }));

        this.mBindings.inputQtaTotText.setOnClickListener(new DoubleClick(new DoubleClickListener() {
            @Override
            public void onSingleClick(View view) {
                String a = "";
            }

            @Override
            public void onDoubleClick(View view) {
                mViewModel.blockedQtaTot.set(!mViewModel.blockedQtaTot.get());
            }
        }));


        this.mViewModel.setCanPartitaMagBeChanged(this.mDialogInputQuantityV2DTO.isCanPartitaMagBeChanged());
        this.enabledChangePartitaMag.set(this.mDialogInputQuantityV2DTO.isCanPartitaMagBeChanged());
        this.enabledLUCloseButton.set(this.mDialogInputQuantityV2DTO.isCanLUBeClosed());
    }


    private void toggleTextInputLayoutError(ColorStateList originalColorStateList, TextInputLayout textInputLayout, boolean isError) {
        if (isError) {
            textInputLayout.setErrorEnabled(true);
            textInputLayout.setError(" ");
            textInputLayout.setErrorIconDrawable(null);
            textInputLayout.getEditText().setTextColor(ContextCompat.getColor(this.context, R.color.red_600));
            textInputLayout.setHintTextAppearance(R.style.ErrorFloatingLabel);
        } else {
            textInputLayout.setErrorEnabled(false);
            textInputLayout.setError(null);
            textInputLayout.getEditText().setTextColor(originalColorStateList);
            textInputLayout.setHintTextAppearance(R.style.NormalFloatingLabel);
        }
    }

    @Override
    public void onDataChanged() {
        this.mEnableDataCallback = false;

        this.currentPartitaMag.set(this.mViewModel.getPartitaMag());
        this.currentDataScad.set(this.mViewModel.getDataScad());

        this.currentNumCnf.set(this.mViewModel.getNumCnf());
        this.currentQtaCnf.set(this.mViewModel.getQtaCnf());
        this.currentQtaTot.set(this.mViewModel.getQtaTot());

        this.mBindings.executePendingBindings();

        this.mEnableDataCallback = true;
    }

    @Override
    public void onError(Exception ex) {
        DialogSimpleMessageView
                .makeErrorDialog(new SpannableString(Html.fromHtml(ex.getMessage())), null, null)
                .show(requireActivity().getSupportFragmentManager(), "tag");
    }
}
