package it.integry.integrywmsnative.gest.pv_ordine_acquisto_edit;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.Html;
import android.text.SpannableString;
import android.view.View;
import android.widget.Toast;

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

import com.ravikoradiya.liveadapter.LiveAdapter;
import com.ravikoradiya.liveadapter.Type;

import java.util.List;

import javax.inject.Inject;

import it.integry.barcode_base_android_library.model.BarcodeScanDTO;
import it.integry.integrywmsnative.BR;
import it.integry.integrywmsnative.MainApplication;
import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.barcode_reader.BarcodeCallbackDTO;
import it.integry.integrywmsnative.core.barcode_reader.BarcodeManager;
import it.integry.integrywmsnative.core.data_cache.DataCache;
import it.integry.integrywmsnative.core.data_store.db.entity.ArticoloOrdine;
import it.integry.integrywmsnative.core.data_store.db.entity.Ordine;
import it.integry.integrywmsnative.core.data_store.db.view_model.ArticoloDTO;
import it.integry.integrywmsnative.core.expansion.BaseActivity;
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.settings.SettingsManager;
import it.integry.integrywmsnative.core.utility.UtilityDate;
import it.integry.integrywmsnative.databinding.ActivityPvOrdineAcquistoEditBinding;
import it.integry.integrywmsnative.databinding.FragmentPvArticoliOrdineAcquistoListSingleItemBinding;
import it.integry.integrywmsnative.gest.pv_ordine_acquisto_edit.dialog.DialogEditArticoloView;
import it.integry.integrywmsnative.ui.FabMenuCustomAnimations;
import it.integry.integrywmsnative.ui.SimpleDividerItemDecoration;
import it.integry.integrywmsnative.view.dialogs.DialogAskActionView;
import it.integry.integrywmsnative.view.dialogs.base.DialogSimpleInputHelper;
import it.integry.integrywmsnative.view.dialogs.base.DialogSimpleMessageView;

public class PVOrdineAcquistoEditActivity extends BaseActivity implements PVOrdineAcquistoEditViewModel.Listener {

    private static String DATA_KEY_ORDER = "keyOrdine";
    private static String DATA_LIST_ARTS = "listArts";
    private ActivityPvOrdineAcquistoEditBinding mBinding;
    private int barcodeScannerIstanceID;

    @Inject
    PVOrdineAcquistoEditViewModel mViewModel;

    public static Intent newInstance(Context context, Ordine ordine, List<ArticoloDTO> listArts) {
        Intent myIntent = new Intent(context, PVOrdineAcquistoEditActivity.class);
        String keyOrdine = DataCache.addItem(ordine);
        String keyListArts = DataCache.addItem(listArts);
        myIntent.putExtra(DATA_KEY_ORDER, keyOrdine);
        myIntent.putExtra(DATA_LIST_ARTS, keyListArts);
        return myIntent;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

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


        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_pv_ordine_acquisto_edit);
        mBinding.setViewModel(this);
        Ordine ordine = DataCache.retrieveItem(getIntent().getStringExtra(DATA_KEY_ORDER));
        setSupportActionBar(mBinding.toolbar);
        mBinding.toolbar.setTitle(R.string.edit_order);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
        }

        if (ordine == null) {
            Toast.makeText(this, "Impossibile modificare ordine esportato", Toast.LENGTH_SHORT).show();
            close();
            return;
        }
        if (ordine.isTransmitted()) {
            Toast.makeText(this, "Impossibile modificare ordine esportato", Toast.LENGTH_SHORT).show();
            close();
        }
        String testataOrdString = String.format(this.getString(R.string.ord_acq_testata), ordine.getOrdineId(), UtilityDate.formatDate(ordine.getDataIns(), UtilityDate.COMMONS_DATE_FORMATS.DMY_HUMAN));
        mBinding.orderIdentifier.setText(Html.fromHtml(testataOrdString));
        FabMenuCustomAnimations.changeIconOnFocus(mBinding.closeActivityFab, R.drawable.ic_check_white_24dp, R.drawable.ic_close_24dp);


        initBarcodeReader();
        initRecyclerView();

        this.mViewModel.setListener(this);

        mBinding.codAlis.setText(ordine.getCodAlis());

        this.mViewModel.getArticoli().observe(this, articoli -> {
            mBinding.countArtOrd.setText(String.valueOf(articoli.size()));
            mBinding.pvOrdineExport.setVisibility(articoli.size() > 0 ? View.INVISIBLE : View.GONE);
            mBinding.closeActivityFab.close(false);
            mBinding.scanArtSpinner.setVisibility(articoli.size() > 0 ? View.GONE : View.VISIBLE);

            if (ordine.isOrderNewProducts() && articoli.isEmpty() && isOrderNewProdsForced()) {
                this.mViewModel.orderNewProducts();
                ordine.setOrderNewProducts(false);
            }
        });
        List<ArticoloDTO> articoliGriglia = DataCache.retrieveItem(getIntent().getStringExtra(DATA_LIST_ARTS));

        this.mViewModel.init(ordine, articoliGriglia);
    }

    @Override
    public boolean onSupportNavigateUp() {
        onBackPressed();
        return true;
    }

    private void initBarcodeReader() {
        barcodeScannerIstanceID = BarcodeManager.addCallback(new BarcodeCallbackDTO()
                .setOnScanSuccessful(onScanSuccessful)
                .setOnScanFailed(this::onError));

        BarcodeManager.enable();
    }

    private void initRecyclerView() {

        var itemType = new Type<ArticoloOrdine, FragmentPvArticoliOrdineAcquistoListSingleItemBinding>(R.layout.fragment_pv_articoli_ordine_acquisto__list_single_item, BR.articolo);
        itemType.onClick(x -> {
            this.selectAction(x.getBinding().getArticolo());
            return null;
        });

        new LiveAdapter(this.mViewModel.getArticoli(), this)
                .map(ArticoloOrdine.class, itemType)
                .into(mBinding.articoliOrdineList);

        mBinding.articoliOrdineList.setHasFixedSize(true);
        mBinding.articoliOrdineList.setLayoutManager(new LinearLayoutManager(this));

        SimpleDividerItemDecoration itemDecorator = new SimpleDividerItemDecoration(this, SimpleDividerItemDecoration.VERTICAL);
        itemDecorator.setDrawable(ContextCompat.getDrawable(this, R.drawable.divider));
        mBinding.articoliOrdineList.addItemDecoration(itemDecorator);
    }

    private void selectAction(ArticoloOrdine articoloOrdine) {
        mBinding.closeActivityFab.close(false);
        BarcodeManager.disable();

        DialogAskActionView.newInstance(articoloOrdine.getDescrizione(),
                articoloOrdine.getQtaOrd() + " " + articoloOrdine.getUntMis(),
                () -> this.onItemDispatched(articoloOrdine, () -> {

                }),
                () -> {
                    this.deleteArticolo(articoloOrdine);
                    BarcodeManager.enable();
                }).show(getSupportFragmentManager(), "tag");

    }

    private void deleteArticolo(ArticoloOrdine articoloOrdine) {
        String text = "Stai per eliminare l'articolo <b> " + articoloOrdine.getDescrizione() + "</b>  dall'ordine, <br> sei sicuro?";

        DialogSimpleMessageView.makeWarningDialog(new SpannableString(Html.fromHtml(text)), null, () -> {
            this.mViewModel.deleteArticolo(articoloOrdine);
        }, () -> {

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

    private final RunnableArgs<BarcodeScanDTO> onScanSuccessful = data -> {
        this.mViewModel.processBarcode(data.getStringValue());
    };

    @Override
    public void onItemDispatched(ArticoloOrdine articoloOrdine, Runnable onSuccess) {
        DialogEditArticoloView
                .newInstance(articoloOrdine, articolo -> {
                    if (articolo != null) {
                        Toast.makeText(this, "Articolo aggiunto all'ordine!", Toast.LENGTH_SHORT).show();
                    }
                    this.mViewModel.refreshListArticoli(onSuccess);
                }, null).show(this.getSupportFragmentManager(), "DialogEditArticoloView");
    }

    @Override
    public int getColorFromResource(int resId) {
        return getResources().getColor(resId);
    }

    public void exportOrdine() {
        this.mViewModel.exportOrdine(() -> {
            Toast.makeText(this, "Ordine salvato con successo", Toast.LENGTH_SHORT).show();
            close();
        });
    }

    public void close() {
        onBackPressed();
    }

    @Override
    public void onBackPressed() {
        BarcodeManager.removeCallback(barcodeScannerIstanceID);
        super.onBackPressed();
    }

    public void manualSearch() {
        BarcodeManager.disable();
        DialogSimpleInputHelper.makeInputDialog(this, "Inserisci il codice a barre/codice articolo da cercare", barcode -> {
            this.onLoadingStarted();
            this.mViewModel.processBarcode(barcode);
        }, BarcodeManager::enable).show();
    }

    private boolean isOrderNewProdsForced() {
        return SettingsManager.iDB().getFlagOrdinaNuoviArticoliInGriglia();
    }

}
