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

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.SpannableString;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;

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.annimon.stream.Optional;
import com.annimon.stream.Stream;
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.math.RoundingMode;

import javax.inject.Inject;

import it.integry.integrywmsnative.MainApplication;
import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.expansion.BaseDialogFragment;
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.model.JtbFasi;
import it.integry.integrywmsnative.core.model.MtbAart;
import it.integry.integrywmsnative.core.model.MtbTCol;
import it.integry.integrywmsnative.core.utility.UtilityObservable;
import it.integry.integrywmsnative.databinding.DialogInputLuProdBinding;
import it.integry.integrywmsnative.view.dialogs.base.DialogSimpleMessageView;
import it.integry.integrywmsnative.view.dialogs.input_lu_prod.adapter.DialogInputLULineeProdAdapter;
import it.integry.integrywmsnative.view.dialogs.input_lu_prod.adapter.DialogInputLULineeProdListModel;
import it.integry.integrywmsnative.view.dialogs.input_lu_prod.adapter.DialogInputLUProdTipoColloAdapter;
import it.integry.integrywmsnative.view.dialogs.input_lu_prod.adapter.DialogInputLUProdTipoColloListModel;

public class DialogInputLUProdView extends BaseDialogFragment implements DialogInputLUProdViewModel.Listener {

    @Inject
    DialogInputLUProdViewModel mViewModel;

    private final DialogInputLUProdDTO mDialogInputLUProdDTO;
    private final RunnableArgs<DialogInputLUProdResultDTO> mOnComplete;
    private final Runnable mOnAbort;

    public ObservableField<String> selectedMtbTcol = new ObservableField<>();
    public ObservableField<DialogInputLUProdTipoColloListModel> currentMtbTCol = new ObservableField<>();

    public ObservableField<String> selectedLineaProd = new ObservableField<>();
    public ObservableField<DialogInputLULineeProdListModel> currentLineaProd = new ObservableField<>();

    public ObservableField<MtbAart> currentMtbAart = new ObservableField<>();

    public ObservableField<BigDecimal> currentNumCnf = new ObservableField<>();
    public ObservableField<BigDecimal> currentPesoCollo = new ObservableField<>();
    public ObservableField<BigDecimal> currentPesoNetto = new ObservableField<>();
    public ObservableField<BigDecimal> currentTaraPed = new ObservableField<>();
    public ObservableField<BigDecimal> currentTaraCol = new ObservableField<>();
    public ObservableField<BigDecimal> currentPesoLordo = new ObservableField<>();

    public ObservableField<Boolean> enabledLineeProd = new ObservableField<>(false);

    public ObservableField<Boolean> enabledNumCnf = new ObservableField<>(true);
    public ObservableField<Boolean> enabledQtaCnf = new ObservableField<>(false);
    public ObservableField<Boolean> enabledQtaTot = new ObservableField<>(false);
    public ObservableField<Boolean> enabledTaraPed = new ObservableField<>(false);
    public ObservableField<Boolean> enabledTaraCol = new ObservableField<>(false);
    public ObservableField<Boolean> enabledPesoLordo = new ObservableField<>(true);


    private DialogInputLuProdBinding mBindings;
    private boolean mEnableDataCallback = true;

    private DialogInputLUProdTipoColloAdapter codTcolArrayAdapter = null;
    private DialogInputLULineeProdAdapter lineeProdArrayAdapter = null;

    public static DialogInputLUProdView newInstance(@NotNull DialogInputLUProdDTO dialogInputLUProdDTO, @NotNull RunnableArgs<DialogInputLUProdResultDTO> onComplete, @NotNull Runnable onAbort) {
        return new DialogInputLUProdView(dialogInputLUProdDTO, onComplete, onAbort);
    }

    private DialogInputLUProdView(@NotNull DialogInputLUProdDTO dialogInputLUProdDTO, @NotNull RunnableArgs<DialogInputLUProdResultDTO> onComplete, @NotNull Runnable onAbort) {
        super();

        this.mDialogInputLUProdDTO = dialogInputLUProdDTO;
        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);

    }


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mBindings = DataBindingUtil.inflate(inflater, R.layout.dialog_input_lu_prod, container, false);
        mBindings.setLifecycleOwner(this);

        mBindings.toolbar.setTitle("Creazione pedana");

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

        this.mViewModel
                .setMtbAart(mDialogInputLUProdDTO.getMtbAart())
                .setInitialNumCnf(mDialogInputLUProdDTO.getNumCnf())
                .setInitialPesoCollo(mDialogInputLUProdDTO.getQtaCnf())
                .setInitialPesoNetto(mDialogInputLUProdDTO.getQtaTot());

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

        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        getDialog().setCanceledOnTouchOutside(false);
        getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

        return mBindings.getRoot();
    }

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

        this.mViewModel.setListener(this);
        this.mViewModel.init(mDialogInputLUProdDTO.getCodJfasParent());
    }


    private void init() {
        UtilityObservable.addPropertyChanged(this.currentMtbAart, (value) -> {
            this.currentTaraCol.set(value.getTaraKg());
        });

        UtilityObservable.addPropertyChanged(this.selectedMtbTcol, (value) -> {
            if(this.codTcolArrayAdapter != null && this.codTcolArrayAdapter.getDataset() != null) {
                Optional<DialogInputLUProdTipoColloListModel> selectedItem = Stream.of(this.codTcolArrayAdapter.getDataset())
                        .filter(x -> x.toString().equals(value))
                        .findFirst();

                if(selectedItem.isPresent()) {
                    currentMtbTCol.set(selectedItem.get());
                    this.mViewModel.setInternalTipoPed(selectedItem.get().getOriginalModel());
                }
            }
        });

        UtilityObservable.addPropertyChanged(this.currentMtbTCol, (value) -> {
            this.currentTaraPed.set(value.getOriginalModel().getTaraKg());
        });

        UtilityObservable.addPropertyChanged(this.selectedLineaProd, (value) -> {
            if(this.lineeProdArrayAdapter != null && this.lineeProdArrayAdapter.getDataset() != null) {
                Optional<DialogInputLULineeProdListModel> selectedItem = Stream.of(this.lineeProdArrayAdapter.getDataset())
                        .filter(x -> x.toString().equals(value))
                        .findFirst();

                if(selectedItem.isPresent()) {
                    currentLineaProd.set(selectedItem.get());
                    this.mViewModel.setInternalLineaProd(selectedItem.get().getOriginalModel());
                }
            }
        });

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

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

        UtilityObservable.addPropertyChanged(this.currentPesoNetto, (value) -> {
            if(value != null) {
                this.currentPesoNetto.set(value.setScale(0, RoundingMode.HALF_UP));
            }
            if (this.mEnableDataCallback) {
                this.mViewModel.setPesoNetto(value);
            }
        });

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

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

        UtilityObservable.addPropertyChanged(this.currentPesoLordo, (value) -> {
            if(value != null) {
                this.currentPesoLordo.set(value.setScale(0, RoundingMode.HALF_UP));
            }
            if (this.mEnableDataCallback) {
                this.mViewModel.setPesoLordo(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();
        final ColorStateList textColorsTaraPed = this.mBindings.inputTaraPedLayout.getEditText().getTextColors();
        final ColorStateList textColorsTaraCol = this.mBindings.inputTaraColLayout.getEditText().getTextColors();
        final ColorStateList textColorsPesoLor = this.mBindings.inputPesoLordoLayout.getEditText().getTextColors();

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

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

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

        UtilityObservable.addPropertyChanged(this.mViewModel.blockedTaraPed, (value) -> {
            toggleTextInputLayoutError(textColorsTaraPed, this.mBindings.inputTaraPedLayout, value);
        });

        UtilityObservable.addPropertyChanged(this.mViewModel.blockedTaraCol, (value) -> {
            toggleTextInputLayoutError(textColorsTaraCol, this.mBindings.inputTaraColLayout, value);
        });

        UtilityObservable.addPropertyChanged(this.mViewModel.blockedPesoLordo, (value) -> {
            toggleTextInputLayoutError(textColorsPesoLor, this.mBindings.inputPesoLordoLayout, value);
        });

        //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.blockedPesoCollo.set(!mViewModel.blockedPesoCollo.get());
            }
        }));

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

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

        this.mBindings.filledExposedDropdownCodTcol.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                currentMtbTCol.set(codTcolArrayAdapter.getItem(i));
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {
                currentMtbTCol.set(null);
            }
        });

        this.mBindings.filledExposedDropdownCodTcol.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                currentLineaProd.set(lineeProdArrayAdapter.getItem(i));
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {
                currentLineaProd.set(null);
            }
        });

        this.mViewModel.getTipiCollo().observe(getViewLifecycleOwner(), tipiCollo -> {

            codTcolArrayAdapter = new DialogInputLUProdTipoColloAdapter(getActivity(), R.layout.array_adapter_single_item, tipiCollo);
            mBindings.filledExposedDropdownCodTcol.setAdapter(codTcolArrayAdapter);

            if(mDialogInputLUProdDTO.getCodTcol() != null) {
                Optional<MtbTCol> optTCol = Stream.of(tipiCollo)
                        .filter(x -> x.getCodTcol().equalsIgnoreCase(mDialogInputLUProdDTO.getCodTcol()))
                        .findFirst();

                if(optTCol.isPresent())
                    selectedMtbTcol.set(new DialogInputLUProdTipoColloListModel().setOriginalModel(optTCol.get()).toString());
            }

        });


        this.mViewModel.getLineeProd().observe(getViewLifecycleOwner(), lineeProd -> {
            this.enabledLineeProd.set(lineeProd != null && lineeProd.size() > 0);
            this.mViewModel.setLineeProdRequired(lineeProd != null && lineeProd.size() > 0);

            lineeProdArrayAdapter = new DialogInputLULineeProdAdapter(getActivity(), R.layout.array_adapter_single_item, lineeProd);
            mBindings.filledExposedDropdownCodJfas.setAdapter(lineeProdArrayAdapter);

            if(mDialogInputLUProdDTO.getSuggestedCodJfas() != null) {
                Optional<JtbFasi> optFas = Stream.of(lineeProd)
                        .filter(x -> x.getCodJfas().equalsIgnoreCase(mDialogInputLUProdDTO.getSuggestedCodJfas()))
                        .findFirst();

                if(optFas.isPresent())
                    selectedLineaProd.set(new DialogInputLULineeProdListModel().setOriginalModel(optFas.get()).toString());
            }
        });

        this.currentMtbAart.set(mDialogInputLUProdDTO.getMtbAart());

    }


    private void toggleTextInputLayoutError(ColorStateList originalColorStateList, TextInputLayout textInputLayout, boolean isError) {
        if (isError) {
            textInputLayout.setErrorEnabled(true);
            textInputLayout.setError(" ");
            textInputLayout.setErrorIconDrawable(null);
            textInputLayout.getEditText().setTextColor(ContextCompat.getColor(getActivity(), 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);
        }
    }





    public void resetValues() {
        this.mViewModel.blockedNumCnf.set(false);
        this.mViewModel.blockedPesoLordo.set(false);


        this.mViewModel.setInitialNumCnf(mDialogInputLUProdDTO.getNumCnf());
        this.mViewModel.setInitialPesoCollo(mDialogInputLUProdDTO.getQtaCnf());
        this.mViewModel.setInitialPesoNetto(mDialogInputLUProdDTO.getQtaTot());

        this.mViewModel.refreshPesoLordo();

        this.onDataChanged();
    }


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

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

        this.currentNumCnf.set(this.mViewModel.getNumCnf());
        this.currentPesoCollo.set(this.mViewModel.getPesoCollo());
        this.currentPesoNetto.set(this.mViewModel.getPesoNetto());
        this.currentTaraPed.set(this.mViewModel.getTaraPed());
        this.currentTaraCol.set(this.mViewModel.getTaraCol());
        this.currentPesoLordo.set(this.mViewModel.getPesoLordo());

        this.mBindings.executePendingBindings();

        this.mEnableDataCallback = true;
    }

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