package it.integry.integrywmsnative.core.settings;

import android.content.Context;

import com.google.firebase.perf.metrics.Trace;

import java.util.List;

import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.REST.consumers.ColliMagazzinoRESTConsumer;
import it.integry.integrywmsnative.core.REST.consumers.GestSetupRESTConsumer;
import it.integry.integrywmsnative.core.REST.consumers.ISimpleOperationCallback;
import it.integry.integrywmsnative.core.REST.consumers.SystemRESTConsumer;
import it.integry.integrywmsnative.core.REST.model.AvailableCodMdepsDTO;
import it.integry.integrywmsnative.core.expansion.RunnableArgs;
import it.integry.integrywmsnative.core.utility.UtilityFirebase;

public class SettingsManager {

    private static String TAG = "SETTINGS";

    private static SettingsModel settingsModelIstance;
    private static DBSettingsModel dbSettingsModelIstance;

    private static boolean firstStart = false;

    private static Context mContext;

    public static void init(Context context){
        mContext = context;

        settingsModelIstance = (SettingsModel) Stash.getObject(TAG, SettingsModel.class);

        if(settingsModelIstance == null) {
            settingsModelIstance = new SettingsModel();

            settingsModelIstance.server = new SettingsModel.Server();
            settingsModelIstance.user = new SettingsModel.User();
            settingsModelIstance.userSession = new SettingsModel.UserSession();

            dbSettingsModelIstance = new DBSettingsModel();

            firstStart = true;
        }

        dbSettingsModelIstance = new DBSettingsModel();

    }

    public static SettingsModel i(){
        return settingsModelIstance;
    }
    public static DBSettingsModel iDB(){
        return dbSettingsModelIstance;
    }

    public static boolean isFirstStart(){
        return firstStart;
    }

    public static void update(){
        Stash.put(TAG, settingsModelIstance);
    }







    public static void reloadDBVariables(Runnable onComplete, RunnableArgs<Exception> onFailed){
        dbSettingsModelIstance = new DBSettingsModel();

        Trace perfTrace = UtilityFirebase.getNewPerformanceTrace("db_reload_vars");
        perfTrace.start();

        Runnable tmpOnComplete = () -> {
            perfTrace.stop();
            onComplete.run();
        };

        RunnableArgs<Exception> tmpOnFailed = ex -> {
            perfTrace.putAttribute("failed", "true");
            onFailed.run(ex);
        };

        loadDatiAzienda(() ->
            loadAvailableProfiles(() ->
                loadAvailableCodMdeps(() ->
                    loadAvailablePosizioni(() ->
                        loadGestSetupValues(tmpOnComplete, tmpOnFailed) ,tmpOnFailed), tmpOnFailed), tmpOnFailed), tmpOnFailed);
    }

    private static void loadDatiAzienda(Runnable onComplete, RunnableArgs<Exception> onFailed) {
        SystemRESTConsumer.getAzienda(datiAzienda -> {
            SettingsManager.iDB().setDatiAzienda(datiAzienda);

            if(onComplete != null) onComplete.run();
        }, onFailed);
    }

    private static void loadAvailableProfiles(Runnable onComplete, RunnableArgs<Exception> onFailed){
        SystemRESTConsumer.getAvailableProfiles(new ISimpleOperationCallback<List<String>>() {
            @Override
            public void onSuccess(List<String> availableProfiles) {
                dbSettingsModelIstance.setAvailableProfiles(availableProfiles);

                onComplete.run();

            }

            @Override
            public void onFailed(Exception ex) {
                //BOH
                if(onFailed != null) onFailed.run(ex);
            }
        });
    }

    private static void loadAvailableCodMdeps(Runnable onComplete, RunnableArgs<Exception> onFailed) {
        SystemRESTConsumer.getAvailableCodMdeps(new ISimpleOperationCallback<List<AvailableCodMdepsDTO>>() {
            @Override
            public void onSuccess(List<AvailableCodMdepsDTO> availableCodMdeps) {
                dbSettingsModelIstance.setAvailableCodMdep(availableCodMdeps);

                if(availableCodMdeps == null || availableCodMdeps.size() == 0) {
                    onFailed.run(new Exception(mContext.getText(R.string.no_codmdep_available).toString()));
                    return;
                }

                boolean codMdepExistsAnymore = false;

                if(settingsModelIstance.userSession.depo != null){
                    for(AvailableCodMdepsDTO availableCodMdepDTO : availableCodMdeps){
                        //Controllo se il codMdep salvato esiste ancora
                        if(availableCodMdepDTO.getCodMdep().equalsIgnoreCase(settingsModelIstance.userSession.depo.getCodMdep())) {
                            codMdepExistsAnymore = true;
                            break;
                        }
                    }
                }

                if(!codMdepExistsAnymore){
                    settingsModelIstance.userSession.depo = availableCodMdeps.get(0);
                }

                if(onComplete != null) onComplete.run();
            }

            @Override
            public void onFailed(Exception ex) {
                //BOH
                if(onFailed != null) onFailed.run(ex);
            }
        });
    }


    private static void loadAvailablePosizioni(Runnable onComplete, RunnableArgs<Exception> onFailed) {
        ColliMagazzinoRESTConsumer.getAvailablePosizioni(availablePosizioni -> {
                dbSettingsModelIstance.setAvailablePosizioni(availablePosizioni);

                if(onComplete != null) onComplete.run();
            }, ex -> {
                if(onFailed != null) onFailed.run(ex);
            }
        );
    }


    private static void loadGestSetupValues(Runnable onComplete, RunnableArgs<Exception> onFailed) {
        GestSetupRESTConsumer.getValue("PICKING", "SETUP", "DEFAULT_CAUSALE_RETTIFICA_GIACENZE", valueDefaultCausaleRettificaGiacenze -> {
            dbSettingsModelIstance.setDefaultCausaleRettificaGiacenze(valueDefaultCausaleRettificaGiacenze.value);

            GestSetupRESTConsumer.getBooleanValue("PICKING", "SETUP", "ENABLE_CHECK_PARTITA_MAG_PICKING_V", valueEnableCheckPartitaMag -> {
                dbSettingsModelIstance.setEnableCheckPartitaMagCheckPickingV(valueEnableCheckPartitaMag);

                GestSetupRESTConsumer.getBooleanValue("PICKING", "SETUP", "FLAG_MULTI_CLIENTE_ORD_VENDITA", valueFlagMultiClienteOrdVendita -> {
                dbSettingsModelIstance.setFlagMultiClienteOrdV(valueFlagMultiClienteOrdVendita);

                    GestSetupRESTConsumer.getValue("PICKING", "SETUP", "COD_ANAG_DEFAULT", valueCodAnagDefault -> {
                        dbSettingsModelIstance.setDefaultCodAnag(valueCodAnagDefault.value);

                        if(onComplete != null) onComplete.run();
                    }, ex -> {
                        if(onFailed != null) onFailed.run(ex);
                    });

                }, ex -> {
                    if(onFailed != null) onFailed.run(ex);
                });

            }, ex -> {
                if(onFailed != null) onFailed.run(ex);
            });

        }, ex -> {
            if(onFailed != null) onFailed.run(ex);
        });
    }

}
