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

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

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.SearchView;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.annimon.stream.Stream;

import java.util.ArrayList;
import java.util.List;

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.model.MtbAart;
import it.integry.integrywmsnative.core.model.MtbColr;
import it.integry.integrywmsnative.core.rest.consumers.ArticoloRESTConsumer;
import it.integry.integrywmsnative.core.rest.consumers.BarcodeRESTConsumer;
import it.integry.integrywmsnative.core.rest.model.Ean128Model;
import it.integry.integrywmsnative.core.utility.UtilityBarcode;
import it.integry.integrywmsnative.core.utility.UtilityDialog;
import it.integry.integrywmsnative.core.utility.UtilityExceptions;
import it.integry.integrywmsnative.core.utility.UtilityString;
import it.integry.integrywmsnative.databinding.DialogChooseArtsFromListaArtsLayoutBinding;
import it.integry.integrywmsnative.view.dialogs.DialogCommon;

public class DialogChooseArtsFromListaArts extends BaseDialogFragment {

    @Inject
    BarcodeRESTConsumer barcodeRESTConsumer;

    @Inject
    ArticoloRESTConsumer articoloRESTConsumer;

    private Context context;

    private DialogChooseArtsFromListaArtsLayoutBinding mBindings;
    private DialogChooseArtsFromListaArtsAdapter currentAdapter;

    private final RunnableArgs<List<MtbColr>> mOnItemsChoosed;
    private final Runnable mOnAbort;

    private final List<DialogChooseArtsFromListaArtsItemModel> mDataset;

    private int mBarcodeScannerIstanceID;
    private MtbAart selectedArt;

    public static DialogChooseArtsFromListaArts newInstance(List<MtbColr> listaMtbColr, RunnableArgs<List<MtbColr>> onItemsChoosed, Runnable onAbort) {
        return new DialogChooseArtsFromListaArts(listaMtbColr, onItemsChoosed, onAbort);
    }

    public static DialogChooseArtsFromListaArts newInstance(List<MtbColr> listaMtbColr, MtbAart mtbAart, RunnableArgs<List<MtbColr>> onItemsChoosed, Runnable onAbort) {
        DialogChooseArtsFromListaArts dialog = newInstance(listaMtbColr, onItemsChoosed, onAbort);
        dialog.setSelectedArt(mtbAart);
        return dialog;
    }

    public void setSelectedArt(MtbAart mtbAart) {
        this.selectedArt = mtbAart;
    }

    private DialogChooseArtsFromListaArts(List<MtbColr> listaMtbColr, RunnableArgs<List<MtbColr>> onItemsChoosed, Runnable onAbort) {
        super();

        mOnItemsChoosed = onItemsChoosed;
        mOnAbort = onAbort;

        mDataset = new ArrayList<>();

        if (listaMtbColr != null) {
            for (MtbColr mtbColr : listaMtbColr) {
                if (UtilityString.isNullOrEmpty(mtbColr.getUntMis()) && mtbColr.getMtbAart() != null) {
                    mtbColr.setUntMis(mtbColr.getMtbAart().getUntMis());
                }

                mDataset.add(new DialogChooseArtsFromListaArtsItemModel().setMtbColr(mtbColr));
            }
        }
    }

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

        this.context = getActivity();
        mBindings = DataBindingUtil.inflate(inflater, R.layout.dialog_choose_arts_from_lista_arts_layout, null, false);
        mBindings.setLifecycleOwner(getViewLifecycleOwner());

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

        UtilityDialog.setTo90PercentWidth(context, this);

        mBindings.emptyView.setVisibility(mDataset != null && mDataset.size() > 0 ? View.GONE : View.VISIBLE);


        initRecyclerView();
        initFilter();
        setupBarcode();

        mBindings.positiveButton.setOnClickListener(v -> {
            dismiss();
            onPositiveClick();
        });

        mBindings.negativeButton.setOnClickListener(v -> {
            dismiss();
            onNegativeClick();
        });

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

        return mBindings.getRoot();
    }

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

        if (selectedArt != null) {
            this.loadArticolo(selectedArt.getBarCode(), null);
        }
    }

    private void initRecyclerView() {
        mBindings.listaArts.setNestedScrollingEnabled(false);
        mBindings.listaArts.setHasFixedSize(true);
        mBindings.listaArts.setLayoutManager(new LinearLayoutManager(context));

        currentAdapter = new DialogChooseArtsFromListaArtsAdapter(context, mDataset);
        mBindings.listaArts.setAdapter(currentAdapter);
    }


    private void initFilter() {
        mBindings.mainSearch.setOnCloseListener(() -> {
            this.removeListFilter();
            return true;
        });

        mBindings.mainSearch.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
//                removeListFilter();
//
//                if (!UtilityString.isNullOrEmpty(query) && query.trim().length() > 3) {
//                    List<DialogChooseArtsFromListaArtsItemModel> foundRowsList = Stream.of(mDataset)
//                            .filter(x -> {
//                                String codMart = x.getMtbColr().getMtbAart().getCodMart();
//                                String descrizioneArt = x.getMtbColr().getMtbAart().getDescrizioneEstesa();
//                                String diacod = x.getMtbColr().getMtbAart().getDiacod();
//
//                                return ((codMart.startsWith(query) ||
//                                                codMart.endsWith(query) ||
//                                                codMart.contains(query) ||
//                                                codMart.equalsIgnoreCase(query)) ||
//                                        (descrizioneArt.startsWith(query) ||
//                                                descrizioneArt.endsWith(query) ||
//                                                descrizioneArt.contains(query) ||
//                                                descrizioneArt.equalsIgnoreCase(query)) ||
//                                        (diacod.startsWith(query) ||
//                                                diacod.endsWith(query) ||
//                                                diacod.contains(query) ||
//                                                diacod.equalsIgnoreCase(query))) &&
//                                        !x.isHidden();
//                            })
//                            .toList();
//
//                    for (int i = 0; i < mDataset.size(); i++) {
//                        mDataset.get(i).setHidden(!foundRowsList.contains(mDataset.get(i)));
//                    }
//                }

                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                removeListFilter();

                newText = newText.toLowerCase();

                if (!UtilityString.isNullOrEmpty(newText) && newText.trim().length() > 2) {
                    String finalNewText = newText;
                    List<DialogChooseArtsFromListaArtsItemModel> foundRowsList = Stream.of(mDataset)
                            .filter(x -> {
                                String codMart = x.getMtbColr().getMtbAart().getCodMart().toLowerCase();
                                String descrizioneArt = x.getMtbColr().getMtbAart().getDescrizioneEstesa().toLowerCase();
                                String diacod = x.getMtbColr().getMtbAart().getDiacod();
                                if (!UtilityString.isNullOrEmpty(diacod)) {
                                    diacod = diacod.toLowerCase();
                                }

                                return ((codMart.startsWith(finalNewText) ||
                                        codMart.endsWith(finalNewText) ||
                                        codMart.contains(finalNewText) ||
                                        codMart.equalsIgnoreCase(finalNewText)) ||
                                        (descrizioneArt.startsWith(finalNewText) ||
                                                descrizioneArt.endsWith(finalNewText) ||
                                                descrizioneArt.contains(finalNewText) ||
                                                descrizioneArt.equalsIgnoreCase(finalNewText)) ||
                                        (!UtilityString.isNullOrEmpty(diacod) && (diacod.startsWith(finalNewText) ||
                                                diacod.endsWith(finalNewText) ||
                                                diacod.contains(finalNewText) ||
                                                diacod.equalsIgnoreCase(finalNewText)))) &&
                                        !x.isHidden();
                            })
                            .toList();

                    for (int i = 0; i < mDataset.size(); i++) {
                        mDataset.get(i).setHidden(!foundRowsList.contains(mDataset.get(i)));
                    }
                }

                return true;
            }
        });
    }

    private void setupBarcode() {
        BarcodeManager.enable();

        mBarcodeScannerIstanceID = BarcodeManager.addCallback(new BarcodeCallbackDTO()
                .setOnScanSuccessful(onScanSuccessfull)
                .setOnScanFailed(ex -> UtilityExceptions.defaultException(context, ex, false)));


    }


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


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


        if (UtilityBarcode.isEan13(data)) {
            this.loadArticolo(data.getStringValue(), null);
        } else if (UtilityBarcode.isEtichetta128(data)) {
            this.executeEtichettaEan128(data);
        } else {
            onLoadingEnded();
        }


    };


    private void executeEtichettaEan128(BarcodeScanDTO barcodeScanDTO) {
        this.barcodeRESTConsumer.decodeEan128(barcodeScanDTO, ean128Model -> {

            String barcodeProd = null;

            if (!UtilityString.isNullOrEmpty(ean128Model.Sscc)) barcodeProd = ean128Model.Sscc;
            if (!UtilityString.isNullOrEmpty(ean128Model.Gtin)) barcodeProd = ean128Model.Gtin;
            if (!UtilityString.isNullOrEmpty(ean128Model.Content))
                barcodeProd = ean128Model.Content;


            if (!UtilityString.isNullOrEmpty(barcodeProd)) {

                if (!UtilityString.isNullOrEmpty(ean128Model.Gtin) || !UtilityString.isNullOrEmpty(ean128Model.Content)) {
                    this.loadArticolo(barcodeProd, ean128Model);
                } else {
                    DialogCommon.showNoArtFoundDialog(context, () -> {
                        onLoadingEnded();
                    });

                }


            } else {
                //EAN 128 non completo o comunque mancano i riferimenti al prodotto
                DialogCommon.showNoArtFoundDialog(context, () -> {
                    onLoadingEnded();
                });

            }
        }, this::onError);
    }


    private void loadArticolo(String barcodeProd, Ean128Model ean128Model) {
        if (barcodeProd.length() == 14) {
            barcodeProd = UtilityBarcode.convertITF14toEAN13(barcodeProd);
        }

        String finalBarcodeProd = barcodeProd;
        this.articoloRESTConsumer.getByBarcodeProd(barcodeProd, mtbAartList -> {

            if (mtbAartList != null && mtbAartList.size() > 0) {
                this.mBindings.mainSearch.setQuery(finalBarcodeProd, false);

                this.searchArtInList(mtbAartList.get(0), ean128Model);

                onLoadingEnded();

            } else {

                DialogCommon.showNoArtFoundDialog(context, () -> {
                    onLoadingEnded();
                });
            }

        }, this::onError);
    }


    private void searchArtInList(MtbAart mtbAart, Ean128Model ean128Model) {
        removeListFilter();

        List<DialogChooseArtsFromListaArtsItemModel> foundRowsList = Stream.of(mDataset)
                .filter(x -> x.getMtbColr().getMtbAart().getCodMart().equalsIgnoreCase(mtbAart.getCodMart()) &&
                        !x.isHidden())
                .toList();

        if (foundRowsList.size() == 0) {
            DialogCommon.showNoArtFoundDialog(context, null);
        } else {

            for (int i = 0; i < mDataset.size(); i++) {
                mDataset.get(i).setHidden(!foundRowsList.contains(mDataset.get(i)));
            }
        }
    }


    private void removeListFilter() {
        for (DialogChooseArtsFromListaArtsItemModel itemModel : mDataset) {
            itemModel.setHidden(false);
        }
    }


    private void onPositiveClick() {
        if (mOnItemsChoosed != null) {
            mOnItemsChoosed.run(currentAdapter.getSelectedItems());
        }
    }


    private void onNegativeClick() {
        this.dismiss();
    }

}
