package it.integry.integrywmsnative.gest.accettazione_bolla_elenco;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.databinding.ObservableArrayList;

import com.annimon.stream.Stream;

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

import javax.inject.Inject;

import it.integry.integrywmsnative.MainApplication;
import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.data_cache.DataCache;
import it.integry.integrywmsnative.core.di.BindableBoolean;
import it.integry.integrywmsnative.core.expansion.BaseFragment;
import it.integry.integrywmsnative.core.interfaces.IScrollableFragment;
import it.integry.integrywmsnative.core.interfaces.ITitledFragment;
import it.integry.integrywmsnative.core.utility.UtilityDate;
import it.integry.integrywmsnative.databinding.FragmentMainAccettazioneBollaBinding;
import it.integry.integrywmsnative.gest.accettazione_bolla_elenco.rest.dto.SitBollaAccettazioneDTO;
import it.integry.integrywmsnative.gest.accettazione_bolla_elenco.rest.dto.TestataBollaAccettazioneDTO;
import it.integry.integrywmsnative.gest.accettazione_bolla_elenco.ui.MainAccettazioneBolleElencoAdapter;
import it.integry.integrywmsnative.gest.accettazione_bolla_elenco.ui.MainAccettazioneBolleElencoListModel;
import it.integry.integrywmsnative.gest.accettazione_bolla_picking.AccettazioneBollaPickingActivity;
import it.integry.integrywmsnative.ui.ElevatedToolbar;

public class MainAccettazioneBollaElencoFragment extends BaseFragment implements ITitledFragment, IScrollableFragment, MainAccettazioneBollaElencoViewModel.Listener {


    @Inject
    MainAccettazioneBollaElencoViewModel mViewModel;


    private final ObservableArrayList<MainAccettazioneBolleElencoListModel> mBolleInevaseMutableData = new ObservableArrayList<>();
    private FragmentMainAccettazioneBollaBinding mBinding;
    private ElevatedToolbar mToolbar;
    private AppCompatTextView mAppBarTitle;

    public BindableBoolean fabVisible = new BindableBoolean(false);

    private String mTextFilter;


    private final List<Runnable> mOnPreDestroyList = new ArrayList<>();


    public MainAccettazioneBollaElencoFragment() {
    }

    public static MainAccettazioneBollaElencoFragment newInstance() {
        return new MainAccettazioneBollaElencoFragment();
    }


    @Override
    public void onCreateActionBar(AppCompatTextView titleText, Context context) {
        mAppBarTitle = titleText;
        mAppBarTitle.setText(context.getText(R.string.accettazione_ordine_title_fragment).toString());
    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        onLoadingEnded();
        outState.putString("mToolbar", DataCache.addItem(mToolbar));

        super.onSaveInstanceState(outState);
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        setRetainInstance(true);

        if (savedInstanceState != null && savedInstanceState.containsKey("mToolbar"))
            mToolbar = DataCache.retrieveItem(savedInstanceState.getString("mToolbar"));

        mBinding = FragmentMainAccettazioneBollaBinding.inflate(inflater, container, false);

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

        mViewModel.setListener(this);

        mBinding.setLifecycleOwner(this);
        mBinding.setView(this);

        this.initRecyclerView();

        mToolbar.setRecyclerView(mBinding.accettazioneMainList);

        return mBinding.getRoot();
    }


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

        this.fabVisible.set(false);
        mViewModel.init();
    }

    @Override
    public void onDestroy() {
        for (Runnable onPreDestroy : mOnPreDestroyList) {
            onPreDestroy.run();
        }
        super.onDestroy();
    }

    private void initRecyclerView() {
        this.mViewModel.getBolleList().observe(getViewLifecycleOwner(), x -> {
            this.refreshList();
        });


        MainAccettazioneBolleElencoAdapter adapter = new MainAccettazioneBolleElencoAdapter(getActivity(), mBolleInevaseMutableData)
                .setOnGroupItemClicked(x -> {
                    Stream.of(mBolleInevaseMutableData)
                            .filter(y -> !y.getGroupTitle().equalsIgnoreCase(x) && y.getSelectedObservable().get())
                            .forEach(y -> y.getSelectedObservable().set(false));

                    boolean allSelected = Stream.of(mBolleInevaseMutableData)
                            .filter(y -> y.getGroupTitle().equalsIgnoreCase(x))
                            .allMatch(y -> y.getSelectedObservable().get());

                    Stream.of(mBolleInevaseMutableData)
                            .filter(y -> y.getGroupTitle().equalsIgnoreCase(x))
                            .forEach(y -> y.getSelectedObservable().set(!allSelected));
                })
                .setOnItemChecked(x -> {
                    Stream.of(mBolleInevaseMutableData)
                            .filter(y -> !y.getGroupTitle().equalsIgnoreCase(x.getGroupTitle()) && y.getSelectedObservable().get())
                            .forEach(y -> y.getSelectedObservable().set(false));

                    fabVisible.set(Stream.of(mBolleInevaseMutableData)
                            .anyMatch(y -> y.getSelectedObservable().get()));
                });

        adapter.setEmptyView(this.mBinding.bolleAccettazioneEmptyView);

        this.mBinding.accettazioneMainList.setAdapter(adapter);

        if (mToolbar != null)
            mToolbar.setRecyclerView(this.mBinding.accettazioneMainList);
    }


    private void refreshList() {
        List<TestataBollaAccettazioneDTO> tmpList = mViewModel.getBolleList().getValue();

        //TODO: Filter here

        this.mBolleInevaseMutableData.clear();

        if(tmpList != null)
            this.mBolleInevaseMutableData.addAll(convertDataModelToListModel(tmpList));
    }

    @Override
    public void setScrollToolbar(ElevatedToolbar toolbar) {
        mToolbar = toolbar;
    }


    @Override
    public void addOnPreDestroy(Runnable onPreDestroy) {
        this.mOnPreDestroyList.add(onPreDestroy);
    }





    private List<MainAccettazioneBolleElencoListModel> convertDataModelToListModel(List<TestataBollaAccettazioneDTO> dataList) {
        if(dataList == null)
            return null;

        final Comparator<TestataBollaAccettazioneDTO> comparer = Comparator.comparing(TestataBollaAccettazioneDTO::getListino)
                .thenComparing(TestataBollaAccettazioneDTO::getRagSoc)
                .thenComparing(TestataBollaAccettazioneDTO::getNumDoc);

        return Stream.of(dataList)
                .sorted(comparer)
                .map(x -> {
                    MainAccettazioneBolleElencoListModel listModel = new MainAccettazioneBolleElencoListModel();

                    listModel.setOriginalModel(x);
                    listModel.setGroupTitle(x.getListino() + " - " + x.getRagSoc());
                    listModel.setDescription(String.format(getString(R.string.ord_acq_testata), x.getNumDoc(), UtilityDate.formatDate(x.getDataDoc(), UtilityDate.COMMONS_DATE_FORMATS.DMY_HUMAN)));

                    listModel.setSubDescription(x.getDescrizioneListino());
                    listModel.setRightDescription(x.getCodAnag());
                    listModel.setRightSubDescription(x.getCodJcom());

                    return listModel;
                })
                .toList();
    }


    public void dispatchBolle() {
        List<TestataBollaAccettazioneDTO> selectedBolle = Stream.of(this.mBolleInevaseMutableData)
                .filter(x -> x.getSelectedObservable().get())
                .map(MainAccettazioneBolleElencoListModel::getOriginalModel)
                .toList();

        this.mViewModel.loadPicking(selectedBolle);
    }

    @Override
    public void onPickingReady(List<TestataBollaAccettazioneDTO> bolle, List<SitBollaAccettazioneDTO> sitArts) {
        AccettazioneBollaPickingActivity.startActivity(requireContext(), bolle, sitArts);
    }
}
