package it.integry.integrywmsnative.gest.spedizione.dialogs.row_info.info_situazione_articolo;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.annimon.stream.Stream;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.ravikoradiya.liveadapter.LiveAdapter;

import org.jetbrains.annotations.NotNull;

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

import javax.inject.Inject;

import it.integry.integrywmsnative.BR;
import it.integry.integrywmsnative.MainApplication;
import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.model.MvwSitArtUdcDetInventario;
import it.integry.integrywmsnative.core.rest.consumers.GiacenzaRESTConsumer;
import it.integry.integrywmsnative.core.rest.model.giacenza.InstantItemSituationIncomingItemDto;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import it.integry.integrywmsnative.core.utility.UtilityDate;
import it.integry.integrywmsnative.databinding.DialogInfoSituazioneArticoloBinding;
import it.integry.integrywmsnative.gest.spedizione.dialogs.row_info.BaseDialogRowInfoView;
import it.integry.integrywmsnative.gest.spedizione.dialogs.row_info.info_situazione_articolo.ui.DialogInfoSituazioneArticoloAvailableListItem;
import it.integry.integrywmsnative.gest.spedizione.ui.SpedizioneListModel;

public class DialogInfoSituazioneArticoloView extends BaseDialogRowInfoView {

    @Inject
    DialogInfoSituazioneArticoloViewModel mViewModel;

    @Inject
    GiacenzaRESTConsumer giacenzaRESTConsumer;

    private DialogInfoSituazioneArticoloBinding mBindings;
    private Context mContext;

    public DialogInfoSituazioneArticoloView(@NotNull SpedizioneListModel spedizioneListModel, @NotNull Runnable onComplete, @NotNull Runnable onAbort) {
        super(spedizioneListModel, onComplete, onAbort);
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        this.mContext = requireContext();

        mBindings = DialogInfoSituazioneArticoloBinding.inflate(LayoutInflater.from(this.mContext), null, false);
        mBindings.setLifecycleOwner(this);

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

        setCancelable(true);

        var alertDialog = new MaterialAlertDialogBuilder(this.mContext)
                .setView(mBindings.getRoot())
                .setNeutralButton(R.string.action_close, null)
                .setCancelable(isCancelable())
                .create();

        alertDialog.setCanceledOnTouchOutside(isCancelable());
        alertDialog.setOnShowListener(this);
        return alertDialog;
    }

    @Override
    public void onShow(DialogInterface dialogInterface) {
        super.onShow(dialogInterface);

        this.onLoadingStarted();

        String codMdep = SettingsManager.i().getUserSession().getDepo().getCodMdep();
        String codMart = getSpedizioneListModel().getOriginalModel().getSitArtOrdDTO().getCodMart();
        String partitaMag = getSpedizioneListModel().getOriginalModel().getSitArtOrdDTO().getPartitaMag();
        String codJcom = getSpedizioneListModel().getOriginalModel().getSitArtOrdDTO().getCodJcom();

        giacenzaRESTConsumer.getInstantItemSituation(
                codMdep,
                codMart,
                partitaMag,
                codJcom,
                result -> {
                    this.initIncomingItemsList(result.getIncomingItems());
                    this.initAvailableItemsList(result.getAvailableItems());

                    this.onLoadingEnded();
                }, this::onError);
    }


    private void initIncomingItemsList(List<InstantItemSituationIncomingItemDto> incomingItems) {
        mBindings.incomingLabel.setVisibility(incomingItems == null || incomingItems.isEmpty() ? View.GONE : View.VISIBLE);

        if(incomingItems == null || incomingItems.isEmpty())
            return;

        new LiveAdapter(incomingItems, BR.item)
                .map(InstantItemSituationIncomingItemDto.class, R.layout.dialog_info_situazione_articolo_incoming_list_item)
                .into(this.mBindings.incomingList);
    }


    private void initAvailableItemsList(List<MvwSitArtUdcDetInventario> availableItems) {
        mBindings.availableLabel.setVisibility(availableItems == null || availableItems.isEmpty() ? View.GONE : View.VISIBLE);

        if(availableItems == null)
            availableItems = new ArrayList<>();

        availableItems = Stream.of(availableItems)
                .filter(x -> x.getDataScad() == null || UtilityDate.isAfterToday(x.getDataScad()))
                .toList();

        if(availableItems.isEmpty())
            return;

        var preferedCodJcom = getSpedizioneListModel().getOriginalModel().getSitArtOrdDTO().getCodJcom();
        var preferedPartitaMag = getSpedizioneListModel().getOriginalModel().getSitArtOrdDTO().getPartitaMag();

        var itemList = Stream.of(availableItems)
                .map(mvwSitArtUdcDetInventario -> DialogInfoSituazioneArticoloAvailableListItem.fromMvwSitArtUdcDetInventario(mvwSitArtUdcDetInventario)
                        .setCommessaMatch(mvwSitArtUdcDetInventario.getCodJcom() != null && mvwSitArtUdcDetInventario.getCodJcom().equalsIgnoreCase(preferedCodJcom))
                        .setPartitaMagMatch(mvwSitArtUdcDetInventario.getPartitaMag() != null && mvwSitArtUdcDetInventario.getPartitaMag().equalsIgnoreCase(preferedPartitaMag)))
                .toList();


        var itemListCommessaMatch = Stream.of(itemList)
                .filter(DialogInfoSituazioneArticoloAvailableListItem::isCommessaMatch)
                .toList();

        var itemListCommessaNotMatchMatch = Stream.of(itemList)
                .filter(dialogInfoSituazioneArticoloAvailableListItem -> !dialogInfoSituazioneArticoloAvailableListItem.isCommessaMatch())
                .sortBy(x -> x.getDataScad() == null ? UtilityDate.getNow() : x.getDataScad())
                .toList();


        itemListCommessaMatch.addAll(itemListCommessaNotMatchMatch);

        new LiveAdapter(itemListCommessaMatch, BR.item)
                .map(DialogInfoSituazioneArticoloAvailableListItem.class, R.layout.dialog_info_situazione_articolo_available_list_item)
                .into(this.mBindings.availableList);
    }
}