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

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 android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.FragmentActivity;

import com.annimon.stream.Stream;
import com.google.gson.reflect.TypeToken;

import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Type;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import it.integry.integrywmsnative.MainApplication;
import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.expansion.BaseDialogFragment;
import it.integry.integrywmsnative.core.expansion.RunnableArgss;
import it.integry.integrywmsnative.core.model.VtbDest;
import it.integry.integrywmsnative.core.rest.consumers.SystemRESTConsumer;
import it.integry.integrywmsnative.core.utility.UtilityDialog;
import it.integry.integrywmsnative.core.utility.UtilityHashMap;
import it.integry.integrywmsnative.core.utility.UtilityString;
import it.integry.integrywmsnative.databinding.DialogAskClienteBinding;
import it.integry.integrywmsnative.view.dialogs.DialogProgressView;
import it.integry.integrywmsnative.view.dialogs.ask_cliente.dto.DialogAskClienteClienteDTO;
import it.integry.integrywmsnative.view.dialogs.ask_cliente.dto.DialogAskClienteDestinatarioDTO;
import it.integry.integrywmsnative.view.dialogs.ask_cliente.viewmodel.DialogAskCliente_Page1ViewModel;
import it.integry.integrywmsnative.view.dialogs.ask_cliente.viewmodel.DialogAskCliente_Page2ViewModel;
import it.integry.integrywmsnative.view.dialogs.ask_cliente.viewmodel.IDialogAskClienteViewModel;

public class DialogAskClienteView extends BaseDialogFragment {

    private final RunnableArgss<VtbDest, String> mOnComplete;
    private final Runnable mOnAbort;

    private DialogAskClienteAdapter mAdapter;

    private FragmentActivity mContext;
    private DialogAskClienteBinding mBindings;

    private boolean mIsClienteSelected = false;

    @Inject
    SystemRESTConsumer systemRESTConsumer;

    @Inject
    DialogProgressView dialogProgressView;

    public static DialogAskClienteView newInstance(@NotNull RunnableArgss<VtbDest, String> onComplete, @NotNull Runnable onAbort) {
        return new DialogAskClienteView(onComplete, onAbort);
    }

    private DialogAskClienteView(@NotNull RunnableArgss<VtbDest, String> onComplete, @NotNull Runnable onAbort) {
        super();

        this.mOnComplete = onComplete;
        this.mOnAbort = onAbort;
    }


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        this.mContext = getActivity();

        mBindings = DataBindingUtil.inflate(inflater, R.layout.dialog_ask_cliente, container, false);
        mBindings.setLifecycleOwner(this);

        getDialog().setCanceledOnTouchOutside(false);
        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

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


        List<Map.Entry<Integer, Class<? extends IDialogAskClienteViewModel>>> views = new ArrayList<>();
        views.add(new AbstractMap.SimpleEntry<>(R.layout.dialog_ask_cliente__page1, DialogAskCliente_Page1ViewModel.class));
        views.add(new AbstractMap.SimpleEntry<>(R.layout.dialog_ask_cliente__page2, DialogAskCliente_Page2ViewModel.class));

        mAdapter = new DialogAskClienteAdapter(mContext, views);
        mBindings.viewpager.setAdapter(mAdapter);
        mBindings.viewpager.beginFakeDrag();
        mBindings.viewpager.addOnPageChangeListener(mAdapter);
        mBindings.viewpager.setCurrentItem(0, false);

        this.initView();

        return mBindings.getRoot();
    }

    @Override
    public void onStart() {
        super.onStart();
        UtilityDialog.setTo90PercentWidth(this.mContext, this);
    }


    private void initView() {
        DialogAskCliente_Page1ViewModel viewModel1 = (DialogAskCliente_Page1ViewModel) mAdapter.getViewModel(R.layout.dialog_ask_cliente__page1);
        DialogAskCliente_Page2ViewModel viewModel2 = (DialogAskCliente_Page2ViewModel) mAdapter.getViewModel(R.layout.dialog_ask_cliente__page2);

        viewModel1.setOnConfirmClickListener(() -> {
            String codAnag = viewModel1.getCurrentCliente();

            if (UtilityString.isNullOrEmpty(codAnag)) {
                this.mIsClienteSelected = true;
                dismiss();
                mOnComplete.run(null, null);
            }

            viewModel2.setCodAnag(codAnag);

            mBindings.viewpager.setCurrentItem(mBindings.viewpager.getCurrentItem() + 1, true);
        });
        viewModel2.setOnConfirmClickListener(() -> {
            DialogAskClienteDestinatarioDTO cliente = viewModel2.getCurrentDestinatario();

            this.mIsClienteSelected = true;
            dismiss();
            mOnComplete.run(cliente != null ? cliente.toVtbDestModel() : null, viewModel1.getCurrentCommessa());
        });


        viewModel1.setOnAbortClickListener(this::dismiss);
        viewModel2.setOnAbortClickListener(this::dismiss);


        this.dialogProgressView.show(this.getParentFragmentManager(), "tag");

        this.initClienti(viewModel1, () -> {
            this.initDestinatari(viewModel2, () -> {
                this.dialogProgressView.dismiss();
            }, () -> {
                this.dialogProgressView.dismiss();
            });
        }, () -> {
            this.dialogProgressView.dismiss();
        });
    }


    private void initClienti(DialogAskCliente_Page1ViewModel viewModel, Runnable onComplete, Runnable onAbort) {
        Type typeOfObjectsList = new TypeToken<ArrayList<HashMap<String, Object>>>() {
        }.getType();

        String sqlClienti = "SELECT gtb_anag.cod_anag, rag_soc, jtb_comt.cod_jcom " +
                "FROM gtb_anag " +
                "LEFT OUTER JOIN jtb_comt ON gtb_anag.cod_anag = jtb_comt.cod_anag " +
                "INNER JOIN vtb_clie ON gtb_anag.cod_anag = vtb_clie.cod_anag " +
                "WHERE vtb_clie.flag_stato = 'A' " +
                "ORDER BY rag_soc";

        this.systemRESTConsumer.<ArrayList<HashMap<String, Object>>>processSql(sqlClienti, typeOfObjectsList, value -> {
            var availableClienti = new ArrayList<DialogAskClienteClienteDTO>();

            Stream.of(value)
                    .groupBy(x -> x.get("codAnag").toString() + " " + x.get("ragSoc").toString())
                    .forEach(x -> {
                        DialogAskClienteClienteDTO dialogAskClienteClienteDTO = new DialogAskClienteClienteDTO();
                        dialogAskClienteClienteDTO.setCodAnag(UtilityHashMap.getValueIfExists(x.getValue().get(0), "codAnag"));
                        dialogAskClienteClienteDTO.setRagSoc(UtilityHashMap.getValueIfExists(x.getValue().get(0), "ragSoc"));

                        for (HashMap<String, Object> group : x.getValue()) {
                            if (group.containsKey("codJcom")) {
                                dialogAskClienteClienteDTO.getCodJcoms().add(UtilityHashMap.getValueIfExists(group, "codJcom"));
                            }
                        }

                        availableClienti.add(dialogAskClienteClienteDTO);
                    });

            viewModel.setAvailableClienti(availableClienti);
            onComplete.run();
        }, ex -> {
            onAbort.run();
        });
    }

    private void initDestinatari(DialogAskCliente_Page2ViewModel viewModel, Runnable onComplete, Runnable onAbort) {
        String sql = "SELECT vtb_dest.cod_anag,\n" +
                "       cod_vdes,\n" +
                "       destinatario,\n" +
                "       indirizzo,\n" +
                "       cap,\n" +
                "       citta,\n" +
                "       prov,\n" +
                "       nazione\n" +
                "FROM vtb_dest\n" +
                "INNER JOIN vtb_clie ON vtb_clie.cod_anag = vtb_dest.cod_anag\n" +
                "WHERE vtb_clie.flag_stato = 'A'";

        Type typeOfObjectsList = new TypeToken<ArrayList<DialogAskClienteDestinatarioDTO>>() {
        }.getType();
        this.systemRESTConsumer.<ArrayList<DialogAskClienteDestinatarioDTO>>processSql(sql, typeOfObjectsList, value -> {
            viewModel.setAvailableDestinatari(value);

            onComplete.run();
        }, ex -> {
            onAbort.run();
        });

    }

    @Override
    public void onDismiss(@NonNull DialogInterface dialog) {
        mAdapter.onDismiss();
        if (!mIsClienteSelected) {
            this.mOnAbort.run();
        }
        super.onDismiss(dialog);
    }

}
