package it.integry.integrywmsnative.gest.pv_ordini_acquisto;

import android.content.Context;
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.widget.Toast;

import androidx.appcompat.widget.AppCompatTextView;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.LinearLayoutManager;

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

import javax.inject.Inject;

import it.integry.integrywmsnative.MainApplication;
import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.barcode_reader.BarcodeManager;
import it.integry.integrywmsnative.core.data_store.db.entity.Griglia;
import it.integry.integrywmsnative.core.data_store.db.entity.Ordine;
import it.integry.integrywmsnative.core.data_store.db.repository.ArticoliOrdineRepository;
import it.integry.integrywmsnative.core.data_store.db.repository.ArticoloGrigliaRepository;
import it.integry.integrywmsnative.core.data_store.db.repository.GrigliaRepository;
import it.integry.integrywmsnative.core.data_store.db.repository.OrdineRepository;
import it.integry.integrywmsnative.core.data_store.db.view_model.ArticoloDTO;
import it.integry.integrywmsnative.core.data_store.db.wrappers.OrdineWrapper;
import it.integry.integrywmsnative.core.expansion.BaseFragment;
import it.integry.integrywmsnative.core.interfaces.IPoppableActivity;
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.FragmentPvOrdiniAcquistoBinding;
import it.integry.integrywmsnative.gest.pv_ordine_acquisto_edit.PVOrdineAcquistoEditActivity;
import it.integry.integrywmsnative.gest.pv_ordini_acquisto.dialogs.DialogScanGrigliaAcquistoView;
import it.integry.integrywmsnative.gest.pv_ordini_acquisto.ui.OrdineAcquistoPvOpenListAdapter;
import it.integry.integrywmsnative.ui.ElevatedToolbar;
import it.integry.integrywmsnative.ui.SimpleDividerItemDecoration;
import it.integry.integrywmsnative.view.dialogs.DialogAskActionView;
import it.integry.integrywmsnative.view.dialogs.base.DialogSimpleMessageView;

public class PVOrdiniAcquistoGrigliaFragment extends BaseFragment implements ITitledFragment, IScrollableFragment {

    private FragmentPvOrdiniAcquistoBinding mBinding;
    private Griglia mGriglia;
    private OrdineAcquistoPvOpenListAdapter mAdapter;
    private final List<OrdineWrapper> mRenderedOrderList = new ArrayList<>();
    private final List<ArticoloDTO> mListArticoli = new ArrayList<>();
    private boolean mRedirectToNewOrder = true;

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

    @Inject
    GrigliaRepository mGrigliaRepository;

    @Inject
    ArticoliOrdineRepository mArticoliOrdineRepository;

    @Inject
    ArticoloGrigliaRepository mArticoloGrigliaRepository;

    @Inject
    OrdineRepository mOrdineRepository;

    @Inject
    PVOrdiniAcquistoGrigliaViewModel mPvOrdiniAcquistoGrigliaViewModel;

    public PVOrdiniAcquistoGrigliaFragment() {
        // Gets appComponent from MyApplication available in the base Gradle module
        MainApplication.appComponent
                .pvOrdineAcquistoGrigliaComponent()
                .create()
                .inject(this);
    }

    public static PVOrdiniAcquistoGrigliaFragment newInstance() {
        PVOrdiniAcquistoGrigliaFragment fragment = new PVOrdiniAcquistoGrigliaFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment

        mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_pv_ordini_acquisto, container, false);
        mBinding.setViewmodel(this);

        init();
        initRecyclerView();
        return mBinding.getRoot();
    }

    private void init() {
        BarcodeManager.enable();
        DialogScanGrigliaAcquistoView.newInstance((griglia, listArticoli) -> {
            if (griglia == null) {
                ((IPoppableActivity) requireActivity()).pop();
            } else {
                setGriglia(griglia, listArticoli);
            }
        }).show(requireActivity().getSupportFragmentManager(), "tag");

    }

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

    private void setGriglia(Griglia griglia, List<ArticoloDTO> listArticoli) {
        mGriglia = griglia;
        mListArticoli.clear();
        mListArticoli.addAll(listArticoli);
        mBinding.fabNewOrder.setVisibility(View.VISIBLE);
        mBinding.codAlis.setText(griglia.getCodAlis());
        mBinding.descrLis.setText(griglia.getDescrLisa());
        mBinding.descrDepo.setText(griglia.getDescrDepo());
        mBinding.countArtLis.setText(String.valueOf(listArticoli.size()));

        fetchOrders();
    }

    private void fetchOrders() {
        this.onLoadingStarted();

        mOrdineRepository.selectAllOpenOrders(mGriglia.getCodAlis(), ordini -> {
            this.onLoadingEnded();
            requireActivity().runOnUiThread(() -> {
                setOrdini(ordini);
            });
        }, this::onError);
    }

    private void setOrdini(List<OrdineWrapper> ordini) {
        mBinding.ordiniAApertiMainList.setVisibility(ordini != null && ordini.size() > 0 ? View.VISIBLE : View.GONE);
        mBinding.ordiniAEmptyView.setVisibility(ordini == null || ordini.size() <= 0 ? View.VISIBLE : View.GONE);
        refreshRenderedOrdini(ordini);
        mAdapter.updateItems(mRenderedOrderList);
        if (mRenderedOrderList.size() <= 0 && mRedirectToNewOrder) {
            createNewOrder();
        } else {
            mRedirectToNewOrder = false;
        }
    }


    private void initRecyclerView() {
        mBinding.ordiniAApertiMainList.setHasFixedSize(true);
        mBinding.ordiniAApertiMainList.setLayoutManager(new LinearLayoutManager(requireActivity()));

        SimpleDividerItemDecoration itemDecorator = new SimpleDividerItemDecoration(requireActivity(), SimpleDividerItemDecoration.VERTICAL);
        itemDecorator.setDrawable(ContextCompat.getDrawable(requireActivity(), R.drawable.divider));
        mBinding.ordiniAApertiMainList.addItemDecoration(itemDecorator);
        mAdapter = new OrdineAcquistoPvOpenListAdapter(requireActivity(), mRenderedOrderList, this::selectAction);
        mBinding.ordiniAApertiMainList.setAdapter(mAdapter);
    }

    private void editOrdine(Ordine ordine) {
        requireActivity().startActivity(PVOrdineAcquistoEditActivity.newInstance(requireActivity(), ordine, mListArticoli));
    }


    private void selectAction(Ordine ordine) {
        DialogAskActionView.newInstance(Html.fromHtml(String.format(this.getString(R.string.ord_acq_testata), ordine.getOrdineId(), UtilityDate.formatDate(ordine.getDataIns(), UtilityDate.COMMONS_DATE_FORMATS.DMY_HUMAN))).toString(),
                        mListArticoli.size() + " articoli",
                        () -> this.editOrdine(ordine),
                        () -> this.deleteOrdine(ordine))
                .show(requireActivity().getSupportFragmentManager(), "tag");

    }

    private void deleteOrdine(Ordine ordine) {
        String text = "Stai per eliminare un ordine sei sicuro?";

        DialogSimpleMessageView.makeWarningDialog(new SpannableString(Html.fromHtml(text)), null, () -> requireActivity().runOnUiThread(() -> {
            this.onLoadingStarted();
            mPvOrdiniAcquistoGrigliaViewModel.deleteOrder(ordine, () -> {
                requireActivity().runOnUiThread(() -> {
                    this.onLoadingEnded();
                    Toast.makeText(requireActivity(), "Ordine eliminato!", Toast.LENGTH_SHORT).show();
                    fetchOrders();
                });
            }, this::onError);
        }), () -> {

        }).show(requireActivity().getSupportFragmentManager(), "tag");
    }

    private void refreshRenderedOrdini(List<OrdineWrapper> ordini) {
        mRenderedOrderList.clear();
        mRenderedOrderList.addAll(ordini);
    }

    public void createNewOrder() {
        this.onLoadingStarted();

        mPvOrdiniAcquistoGrigliaViewModel.createNewOrder(mGriglia, order -> {
            this.onLoadingEnded();
            requireActivity().runOnUiThread(() -> editOrdine(order));
        }, this::onError);
    }

    @Override
    public void setScrollToolbar(ElevatedToolbar toolbar) {

    }

    @Override
    public void onResume() {
        super.onResume();
        if (mGriglia != null) {
            fetchOrders();
        }
    }

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

        for (Runnable onPreDestroy : mOnPreDestroyList) {
            onPreDestroy.run();
        }
    }

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

}
