package it.integry.integrywmsnative.gest.accettazione;


import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import androidx.databinding.DataBindingUtil;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.appcompat.widget.SearchView;
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 com.annimon.stream.Stream;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import butterknife.ButterKnife;
import butterknife.OnClick;
import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.CommonConst;
import it.integry.integrywmsnative.core.REST.CommonRESTException;
import it.integry.integrywmsnative.core.coollection.Coollection;
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.utility.UtilityString;
import it.integry.integrywmsnative.databinding.FragmentMainAccettazioneBinding;
import it.integry.integrywmsnative.gest.accettazione.core.AccettazioneHelper;
import it.integry.integrywmsnative.gest.accettazione.core.MainListAccettazioneAdapter;
import it.integry.integrywmsnative.gest.accettazione.core.interfaces.ILoadOrdiniCallback;
import it.integry.integrywmsnative.gest.accettazione.core.interfaces.ILoadPickingListCallback;
import it.integry.integrywmsnative.core.interfaces.IRecyclerFragment;
import it.integry.integrywmsnative.core.interfaces.ITitledFragment;
import it.integry.integrywmsnative.gest.accettazione.dto.OrdineAccettazioneDTO;
import it.integry.integrywmsnative.gest.accettazione.dto.OrdineAccettazioneGroupedInevasoDTO;
import it.integry.integrywmsnative.gest.accettazione.dto.OrdineAccettazioneInevasoDTO;
import it.integry.integrywmsnative.gest.accettazione_ordine_inevaso.AccettazioneOrdineInevasoActivity;
import it.integry.integrywmsnative.view.dialogs.DialogSimpleMessageHelper;
import it.integry.plugins.waterfalltoolbar.WaterfallToolbar;

public class MainAccettazioneFragment extends Fragment implements SearchView.OnQueryTextListener, ITitledFragment, IRecyclerFragment {

    private static WaterfallToolbar mWaterfallToolbar;

    private FragmentMainAccettazioneBinding mBinding;

    private AccettazioneHelper helper;

    private List<OrdineAccettazioneGroupedInevasoDTO> groupedOrdiniInevasi;
    private MainListAccettazioneAdapter mAdapter;




    public MainAccettazioneFragment() {
        // Required empty public constructor
    }

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

    @Override
    public String getTitle(Context context){
        return context.getText(R.string.accettazione_title_fragment).toString();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
//            mParam1 = getArguments().getString(ARG_PARAM1);
//            mParam2 = getArguments().getString(ARG_PARAM2);
        }


        init();
    }

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

        mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_main_accettazione, container, false);

        mBinding.setView(this);
        mBinding.accettazioneMainList.setLayoutManager(new LinearLayoutManager(getActivity()));
        mBinding.accettazioneMainFab.hide();

        ButterKnife.bind(this, mBinding.getRoot());

        mWaterfallToolbar.setRecyclerView(mBinding.accettazioneMainList);

        return mBinding.getRoot();
    }




    private void init(){

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

        helper = new AccettazioneHelper(getActivity());

        helper.loadOrdini(new ILoadOrdiniCallback() {
            @Override
            public void onLoadSuccess(List<OrdineAccettazioneInevasoDTO> ordini) {
                Toast.makeText(getActivity(), "Caricati " + ordini.size() + " ordini", Toast.LENGTH_LONG).show();
                groupOrdiniAndMakeRecycler(ordini);
                progress.dismiss();
            }

            @Override
            public void onLoadFail(Exception ex) {
                progress.dismiss();

                String errorMessage = CommonRESTException.tryRecognizeThenGetMessage(ex);
                if(errorMessage == null) errorMessage = ex.getMessage();
                DialogSimpleMessageHelper.makeErrorDialog(getActivity(), new SpannableString(errorMessage), null, null).show();
            }
        });


    }


    private void groupOrdiniAndMakeRecycler(List<OrdineAccettazioneInevasoDTO> ordini){

        String prevCodAnag = "";

        for(OrdineAccettazioneInevasoDTO ordine : ordini){
            if(UtilityString.isNullOrEmpty(ordine.codJcom) || ordine.codJcom.equalsIgnoreCase(CommonConst.Config.COMMESSA_MAG)){
                ordine.codJcom = CommonConst.Config.COMMESSA_MAG;
                ordine.descrizioneCom = "MAGAZZINO";
            }
        }

        groupedOrdiniInevasi = new ArrayList<>();

        //Splitto gli ordini per codAnagClie
        for(int i = 0; i < ordini.size(); i++){
            if(prevCodAnag.equalsIgnoreCase(ordini.get(i).codAnagOrd)) continue;
            else prevCodAnag = ordini.get(i).codAnagOrd;

            OrdineAccettazioneGroupedInevasoDTO groupedOrdine = new OrdineAccettazioneGroupedInevasoDTO();

            groupedOrdine.codAnagForn = ordini.get(i).codAnagOrd;
            groupedOrdine.nomeFornitore = ordini.get(i).ragSocOrd;
            groupedOrdine.ordini = new ArrayList<>();

            List<OrdineAccettazioneInevasoDTO> filteredByCodAnagOrders =
                    Coollection
                            .from(ordini)
                            .where("codAnagOrd", Coollection.eq(ordini.get(i).codAnagOrd)).all();


            int prevNumOrd = -1;
            String prevDataOrd = "";


            //Splitto gli ordini di ogni fornitore per data e numero
            for(int j = 0; j < filteredByCodAnagOrders.size(); j++) {
                if(     prevNumOrd == filteredByCodAnagOrders.get(j).numero &&
                        prevDataOrd.equalsIgnoreCase(filteredByCodAnagOrders.get(j).data)) continue;

                else {
                    prevNumOrd = filteredByCodAnagOrders.get(j).numero;
                    prevDataOrd = filteredByCodAnagOrders.get(j).data;
                }

                OrdineAccettazioneGroupedInevasoDTO.Ordine rigaOrdine = new OrdineAccettazioneGroupedInevasoDTO.Ordine();

                rigaOrdine.data = filteredByCodAnagOrders.get(j).data;
                rigaOrdine.numero = filteredByCodAnagOrders.get(j).numero;
                rigaOrdine.codAnagOrd = filteredByCodAnagOrders.get(j).codAnagOrd;
                rigaOrdine.ragSocOrd = filteredByCodAnagOrders.get(j).ragSocOrd;
                rigaOrdine.pesoTotale = filteredByCodAnagOrders.get(j).pesoTotale;
                rigaOrdine.barcode = filteredByCodAnagOrders.get(j).barcode;
                rigaOrdine.termCons = filteredByCodAnagOrders.get(j).termCons;
                rigaOrdine.dataCons = filteredByCodAnagOrders.get(j).dataCons;
                rigaOrdine.rifOrd = filteredByCodAnagOrders.get(j).rifOrd;
                rigaOrdine.clienti = new ArrayList<>();



                List<OrdineAccettazioneInevasoDTO> filteredByCodAnagAndDateAndNumberOrders =
                        Coollection
                                .from(ordini)
                                .where("codAnagOrd", Coollection.eq(filteredByCodAnagOrders.get(j).codAnagOrd))
                                .and("numero", Coollection.eq(filteredByCodAnagOrders.get(j).numero))
                                .and("data", Coollection.eq(filteredByCodAnagOrders.get(j).data)).all();


                String prevCodJcom = "";

                //Splitto gli ordini per codJcom
                for(int k = 0; k < filteredByCodAnagAndDateAndNumberOrders.size(); k++) {
                    if(prevCodJcom.equalsIgnoreCase(filteredByCodAnagAndDateAndNumberOrders.get(k).codJcom)) continue;
                    else prevCodJcom = filteredByCodAnagAndDateAndNumberOrders.get(k).codJcom;

                    OrdineAccettazioneGroupedInevasoDTO.Cliente cliente = new OrdineAccettazioneGroupedInevasoDTO.Cliente();

                    cliente.codJcom = filteredByCodAnagAndDateAndNumberOrders.get(k).codJcom;
                    cliente.ragSocCom = filteredByCodAnagAndDateAndNumberOrders.get(k).ragSocCom;
                    cliente.descrCom = filteredByCodAnagAndDateAndNumberOrders.get(k).descrizioneCom;
                    cliente.dataCons = filteredByCodAnagAndDateAndNumberOrders.get(k).dataCons;
                    cliente.numCnf = filteredByCodAnagAndDateAndNumberOrders.get(k).numCnf;
                    cliente.rifOrd = filteredByCodAnagAndDateAndNumberOrders.get(k).rifOrd;

                    rigaOrdine.clienti.add(cliente);
                }


                groupedOrdine.ordini.add(rigaOrdine);
            }

            groupedOrdiniInevasi.add(groupedOrdine);
        }

        mAdapter = new MainListAccettazioneAdapter(getActivity(), groupedOrdiniInevasi, onGroupSelectionChanged);
       // mAdapter.setHasStableIds(true);
        mBinding.accettazioneMainList.setAdapter(mAdapter);
        //mRecyclerView.setAdapter(mAdapter);
    }

    @OnClick(R.id.accettazione_main_fab)
    public void onClick(View view) {

        List<OrdineAccettazioneGroupedInevasoDTO> selectedOrders = helper.getSelectedOrders(groupedOrdiniInevasi);
        List<String> barcodes = new ArrayList<>();

        for(OrdineAccettazioneGroupedInevasoDTO ordine : selectedOrders){
            for(OrdineAccettazioneGroupedInevasoDTO.Ordine righeOrd : ordine.ordini){
                barcodes.add(righeOrd.barcode);
            }
        }

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

        helper.retrievePickingList(barcodes, new ILoadPickingListCallback() {
            @Override
            public void onLoadSuccess(final List<OrdineAccettazioneDTO> ordini) {
                progress.dismiss();

                AtomicInteger artsCounter = new AtomicInteger();

                Stream.of(ordini).forEach(x -> {
                    artsCounter.addAndGet((int) Stream.of(x.ordini).filter(y -> y.getQtaDaEvadere().floatValue() > 0).count());
                });

                List<String> ordersKeys = new ArrayList<>();

                for(OrdineAccettazioneDTO ordine : ordini){
                    if(!ordersKeys.contains(ordine.data + " " + ordine.numero + " " + ordine.gestione)){
                        ordersKeys.add(ordine.data + " " + ordine.numero + " " + ordine.gestione);
                    }
                }

                DialogSimpleMessageHelper.makeInfoDialog(getActivity(),
                getText(R.string.orders).toString(),
                                Html.fromHtml(String.format(getActivity().getResources().getQuantityString(R.plurals.loaded_orders_message, ordersKeys.size()), ordersKeys.size())
                                + "<br /><br />" +
                                "<b>" + artsCounter + "</b> " + getActivity().getResources().getQuantityString(R.plurals.available_articles, artsCounter.get())),
                null,
                () -> {

                    Intent myIntent = new Intent(getActivity(), AccettazioneOrdineInevasoActivity.class);
                    myIntent.putExtra("key", (ArrayList<OrdineAccettazioneDTO>) ordini); //Optional parameters
                    getActivity().startActivity(myIntent);

                }).show();

            }

            @Override
            public void onLoadFail(Exception ex) {
//                Toast.makeText(getActivity(), errorMessage, Toast.LENGTH_LONG).show();
                progress.dismiss();

                String errorMessage = CommonRESTException.tryRecognizeThenGetMessage(ex);
                if(errorMessage == null) errorMessage = ex.getMessage() + "\n" + ex.getCause().getCause().getMessage();
                DialogSimpleMessageHelper.makeErrorDialog(getActivity(), new SpannableString(errorMessage), null, null).show();
            }
        });


    }

    RunnableArgs<OrdineAccettazioneGroupedInevasoDTO> onGroupSelectionChanged = dto -> {
        List<OrdineAccettazioneGroupedInevasoDTO> selectedOrders = helper.getSelectedOrders(groupedOrdiniInevasi);

        if(selectedOrders != null && selectedOrders.size() > 1){
            for (OrdineAccettazioneGroupedInevasoDTO selectedOrder : selectedOrders) {
                if(!dto.codAnagForn.equalsIgnoreCase(selectedOrder.codAnagForn)) {
                    Stream.of(selectedOrder.ordini).forEach(x -> x.setCheckbox(false));
                }
            }
        }

        if(selectedOrders.size() > 0) mBinding.accettazioneMainFab.show();
        else mBinding.accettazioneMainFab.hide();
    };





    @Override
    public boolean onQueryTextSubmit(String query) {
        return false;
    }

    @Override
    public boolean onQueryTextChange(String newText) {
        final List<OrdineAccettazioneGroupedInevasoDTO> filtermodelist = helper.getFilteredOrdersByFornitore(groupedOrdiniInevasi, newText);
        mAdapter.setFilter(filtermodelist);
        return true;

    }

    @Override
    public void setWaterfallToolbar(WaterfallToolbar waterfallToolbar) {
        mWaterfallToolbar = waterfallToolbar;
    }
}
