package it.integry.integrywmsnative.view.bottomsheet.viewmodel;

import android.app.ProgressDialog;
import android.content.Context;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.Observable;
import androidx.databinding.ObservableArrayList;
import androidx.databinding.ObservableField;
import androidx.databinding.ObservableList;
import androidx.databinding.ViewDataBinding;
import androidx.annotation.NonNull;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import androidx.appcompat.app.AppCompatActivity;
import android.text.SpannableString;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import java.lang.ref.WeakReference;
import java.math.BigDecimal;

import it.integry.integrywmsnative.BR;
import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.REST.consumers.ColliMagazzinoRESTConsumer;
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.model.MtbColr;
import it.integry.integrywmsnative.core.model.MtbColt;
import it.integry.integrywmsnative.core.utility.UtilityExceptions;
import it.integry.integrywmsnative.core.utility.UtilityNumber;
import it.integry.integrywmsnative.databinding.FragmentArticoliInColloBottomSheetBinding;
import it.integry.integrywmsnative.view.bottomsheet.ArticoliInColloBottomSheetHelper;
import it.integry.integrywmsnative.view.bottomsheet.interfaces.IOnColloClosedCallback;
import it.integry.integrywmsnative.view.dialogs.DialogSimpleMessageHelper;
import it.integry.integrywmsnative.view.dialogs.input_quantity.DialogInputQuantity;

public class ArticoliInColloBottomSheetViewModel {

    public ObservableField<MtbColt> mtbColt = new ObservableField<>();

    private Context mContext;
    private ArticoliInColloBottomSheetHelper mArticoliInColloBottomSheetHelper;

    private IOnColloClosedCallback onCloseColloCallback;


    private FragmentArticoliInColloBottomSheetBinding mBindings;

    private BottomSheetBehavior mBottomSheetBehavior;

    private Runnable mOnItemDeletedCallback;
    private Runnable mOnItemEditedCallback;


    public ArticoliInColloBottomSheetViewModel(AppCompatActivity context, final FragmentArticoliInColloBottomSheetBinding bindings){
        mContext = context;
        mBindings = bindings;
        mArticoliInColloBottomSheetHelper = new ArticoliInColloBottomSheetHelper(context, mBindings);

        mBindings.setViewModel(this);

        mtbColt.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
            @Override
            public void onPropertyChanged(Observable sender, int propertyId) {

                if(mtbColt.get() != null) {

                    mBindings.linearListview.setAdapter(new ArticoliInColloBottomSheetMtbColrAdapter());

                    mBindings.linearListview.setOnItemClickListener((parent, view, position, id) -> {
                        mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);

                        onItemClicked.run(position);
                    });

                    mArticoliInColloBottomSheetHelper.updateRigheNumber(mtbColt.get().getMtbColr().size());
                    mArticoliInColloBottomSheetHelper.initCollo(mtbColt.get());

                    mtbColt.get().getMtbColr().addOnListChangedCallback(new SimpleListChangedCallback(() -> {
                        mArticoliInColloBottomSheetHelper.updateRigheNumber(mtbColt.get().getMtbColr().size());
                    }));
                }
            }
        });

        initBottomSheetActions();
    }

    public void setOnItemEditedCallback(Runnable onItemEditedCallback) {
        this.mOnItemEditedCallback = onItemEditedCallback;
    }

    public void setOnItemDeletedCallback(Runnable onItemDeletedCallback) {
        this.mOnItemDeletedCallback = onItemDeletedCallback;
    }

    private void initBottomSheetActions() {
        mBindings.bg.setOnClickListener(v -> mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED));

        mBottomSheetBehavior = BottomSheetBehavior.from(mBindings.bottomSheetActions);

        mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                if (newState == BottomSheetBehavior.STATE_COLLAPSED)
                    mBindings.bg.setVisibility(View.GONE);
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                mBindings.bg.setVisibility(View.VISIBLE);
                mBindings.bg.setAlpha(slideOffset);
            }
        });
    }

    public void setOnCloseColloCallbackListener(final IOnColloClosedCallback onCloseColloCallback){
        this.onCloseColloCallback = onCloseColloCallback;
    }


    public void closeCurrentUL(){
        if(onCloseColloCallback != null) onCloseColloCallback.onColloClosed();
    }

    public boolean isExpanded() {
        return mArticoliInColloBottomSheetHelper.isExpanded();
    }

    public void expand() {
        mArticoliInColloBottomSheetHelper.expand();
    }

    public void collapse() {
        mArticoliInColloBottomSheetHelper.collapse();
    }


    private RunnableArgs<Integer> onItemClicked = (position) -> {

        MtbColr clickedItem = mtbColt.get().getMtbColr().get(position);

        mBindings.bottomSheetActionsTitle.setText(clickedItem.getDescrizione());
        mBindings.bottomSheetActionsSubtitle.setText(clickedItem.getCodMart());

        mBindings.bottomSheetActionsEditBtn.setOnClickListener(v -> onItemEdit(position));

        mBindings.bottomSheetActionsDeleteBtn.setOnClickListener(v -> onItemDelete(position));

        mBindings.bottomSheetActionsQuantity.setText(UtilityNumber.decimalToString(clickedItem.getQtaCol()) +  " " + clickedItem.getUntMis());


    };

    private void onItemEdit(int position) {

        MtbColr itemToEdit = mtbColt.get().getMtbColr().get(position);

        mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);

        DialogInputQuantity.DTO dto = new DialogInputQuantity.DTO()
                .setBatchLot(itemToEdit.getPartitaMag())
                .setQtaDaEvadere(null)
                .setQtaOrd(null)
                .setMtbAart(itemToEdit.getMtbAart())
                .setCanPartitaMagBeChanged(false)
                .setQtaTot(itemToEdit.getQtaCol())
                .setMaxQta(itemToEdit.getQtaCol());

        DialogInputQuantity.makeBase(mContext, dto, false, quantityDTO -> {

            final ProgressDialog progress = ProgressDialog.show(mContext, mContext.getText(R.string.waiting),
                    mContext.getText(R.string.loading) + " ...", true);

            itemToEdit.setQtaCol(new BigDecimal(quantityDTO.qtaTot.get()));

            ColliMagazzinoRESTConsumer.updateRiga(itemToEdit, () ->{
                mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);

                progress.dismiss();
                mtbColt.get().getMtbColr().set(position, itemToEdit);

                if(mOnItemEditedCallback != null) mOnItemEditedCallback.run();
            },
            ex -> UtilityExceptions.defaultException(mContext, ex, progress));

        }).show();
    }

    private void onItemDelete(int position) {


        String text = mContext.getResources().getString(R.string.alert_delete_mtb_colr);
        DialogSimpleMessageHelper.makeWarningDialog(mContext, new SpannableString(text), null, () -> {
            MtbColr itemToDelete = mtbColt.get().getMtbColr().get(position);

            final ProgressDialog progress = ProgressDialog.show(mContext, mContext.getText(R.string.waiting),
                    mContext.getText(R.string.loading) + " ...", true);

            progress.show();

            ColliMagazzinoRESTConsumer.deleteRiga(itemToDelete, () -> {
                mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);

                progress.dismiss();
                mtbColt.get().getMtbColr().remove(position);

                if(this.mOnItemDeletedCallback != null) this.mOnItemDeletedCallback.run();
            }, ex -> UtilityExceptions.defaultException(mContext, ex, progress));
        }, null).show();



    }


    public class ArticoliInColloBottomSheetMtbColrAdapter extends BaseAdapter {


        private final WeakReferenceOnListChangedCallback onListChangedCallback;

        public ArticoliInColloBottomSheetMtbColrAdapter() {
            super();
            this.onListChangedCallback = new WeakReferenceOnListChangedCallback(this);

            mtbColt.get().getMtbColr().addOnListChangedCallback(onListChangedCallback);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            LayoutInflater inflater = LayoutInflater.from(parent.getContext());

            ViewDataBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_articoli_in_collo_bottom_sheet__mtbcolr_item, parent, false);

            final MtbColr item = mtbColt.get().getMtbColr().get(position);
            binding.setVariable(BR.mtbColr, item);
            binding.executePendingBindings();

            if(position % 2 == 1) binding.getRoot().setBackgroundColor(mContext.getResources().getColor(R.color.letturaFacilitataBG));

            return binding.getRoot();
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public Object getItem(int position) {
            return position;
        }

        @Override
        public int getCount() {
            if(mtbColt.get() != null && mtbColt.get().getMtbColr() != null) {

                return mtbColt.get().getMtbColr().size();
            } else return 0;
        }


        public class WeakReferenceOnListChangedCallback extends ObservableList.OnListChangedCallback {

            private final WeakReference<BaseAdapter> adapterReference;

            public WeakReferenceOnListChangedCallback(BaseAdapter baseAdapter) {
                this.adapterReference = new WeakReference<>(baseAdapter);
            }

            @Override
            public void onChanged(ObservableList sender) {
                BaseAdapter adapter = adapterReference.get();
                if (adapter != null) {
                    adapter.notifyDataSetChanged();
                }
            }

            @Override
            public void onItemRangeChanged(ObservableList sender, int positionStart, int itemCount) {
                BaseAdapter adapter = adapterReference.get();
                if (adapter != null) {
                    adapter.notifyDataSetChanged();
                }
            }

            @Override
            public void onItemRangeInserted(ObservableList sender, int positionStart, int itemCount) {
                BaseAdapter adapter = adapterReference.get();
                if (adapter != null) {
                    adapter.notifyDataSetChanged();
                }
            }

            @Override
            public void onItemRangeMoved(ObservableList sender, int fromPosition, int toPosition, int itemCount) {
                BaseAdapter adapter = adapterReference.get();
                if (adapter != null) {
                    adapter.notifyDataSetChanged();
                }
            }

            @Override
            public void onItemRangeRemoved(ObservableList sender, int positionStart, int itemCount) {
                BaseAdapter adapter = adapterReference.get();
                if (adapter != null) {
                    adapter.notifyDataSetChanged();
                }
            }
        }
    }

}
