package br.com.minhavia.minhavia.service;

import android.app.Notification;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import br.com.minhavia.minhavia.dao.PavimentoIrregularDatabase;
import br.com.minhavia.minhavia.firebase.PavimentoIrregularFirebase;
import br.com.minhavia.minhavia.model.DadosFirebase;
import br.com.minhavia.minhavia.model.PavimentoIrregular;
import br.com.minhavia.minhavia.util.CalcularDistancia;
import br.com.minhavia.minhavia.util.Constantes;

public class FirebaseBackgroundService extends Service {

    private static final String TAG = "MV-FirebaseBackground";
    public static String str_receiver = "br.com.minhavia.minhavia.receive";
    private Context context;
    private Intent intent;
    private Handler mHandler = new Handler();
    private Timer mTimer = null;
    private PavimentoIrregularDatabase db;
    private DatabaseReference pavimentoIrregularFirebase;
    private List<PavimentoIrregular> listaIrregulares = null;
    private TimerTaskToGetLocation timerTaskToGetLocation = new TimerTaskToGetLocation();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        startForeground(2, new Notification());

        db = PavimentoIrregularDatabase.getDATABASE(FirebaseBackgroundService.this);
        pavimentoIrregularFirebase = PavimentoIrregularFirebase.getFirebaseDatabase();
        mTimer = new Timer();
        mTimer.schedule(new TimerTaskToGetLocation(), 5, Constantes.TIMER_REPEAT_FIREBASE);
        intent = new Intent(str_receiver);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand()");
        this.context = this;
        timerTaskToGetLocation.doStop();
        timerTaskToGetLocation.cancel();
        timerTaskToGetLocation.setExecutandoThread(false);
        new TimerTaskToGetLocation().run();
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "onDestroy()");
        if (mTimer != null) {
            mTimer.cancel();
        }
        encerrarServico();
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        Log.e(TAG, "onTaskRemoved()");
        timerTaskToGetLocation.doStop();
        timerTaskToGetLocation.cancel();
        timerTaskToGetLocation.setExecutandoThread(false);
        encerrarServico();
        super.onTaskRemoved(rootIntent);
    }

    @Override
    public void onLowMemory() {
        Log.e(TAG, "onLowMemory()");
        timerTaskToGetLocation.doStop();
        timerTaskToGetLocation.cancel();
        timerTaskToGetLocation.setExecutandoThread(false);
        encerrarServico();
        super.onLowMemory();
    }

    private void encerrarServico() {
        if (mTimer != null) {
            mTimer.cancel();
        }
        stopSelf();
    }

    public void enviarPavimentoIrregular() {

        listaIrregulares = db.pavimentoIrregularDAO().getPavimentos(true);


        Log.i(TAG, "Inicio firebase");


            pavimentoIrregularFirebase.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {

                    List<PavimentoIrregular> listaDeletar = new ArrayList<>();
                    if (listaIrregulares != null) {
                        for (final PavimentoIrregular pavimentoIrregular : listaIrregulares) {
                            if(pavimentoIrregular.getIdFirebase() != null) {
                                Iterable<DataSnapshot> listaDataSnapshots = dataSnapshot.child(pavimentoIrregular.getIdFirebase()).getChildren();

                                DadosFirebase pSnapShot = null;
                                DadosFirebase pavimentoIrregularSelecionado = null;
                                for (DataSnapshot d : listaDataSnapshots) {
                                    pSnapShot = (DadosFirebase) d.getValue();
                                    if (pavimentoIrregularSelecionado == null && CalcularDistancia.ehMesmoPonto(pavimentoIrregular.getLatitude(), pavimentoIrregular.getLongitude(), pSnapShot.getLatitude(), pSnapShot.getLongitude())) {
                                        pavimentoIrregularSelecionado = pSnapShot;
                                    }
                                }

                                if (pavimentoIrregularSelecionado != null) {
                                    pavimentoIrregularFirebase.child(pavimentoIrregularSelecionado.getIdFirebase()).push().setValue(pavimentoIrregularSelecionado);
                                } else {
                                    DadosFirebase dadosFirebase = new DadosFirebase();
                                    dadosFirebase.setLatitude(pavimentoIrregular.getLatitude());
                                    dadosFirebase.setLongitude(pavimentoIrregular.getLongitude());
                                    dadosFirebase.setPais(pavimentoIrregular.getPais());
                                    dadosFirebase.setUf(pavimentoIrregular.getUf());
                                    dadosFirebase.setCidade(pavimentoIrregular.getCidade());
                                    dadosFirebase.setLogradouro(pavimentoIrregular.getLogradouro());
                                    pavimentoIrregularFirebase.child("pais").child(pavimentoIrregular.getPais()).
                                            child("uf").child(pavimentoIrregular.getUf()).
                                            child("cidade").child(pavimentoIrregular.getCidade()).
                                            child("logradouro").child(pavimentoIrregular.getLogradouro()).
                                            child(dadosFirebase.getIdFirebase()).
                                            setValue(dadosFirebase);
                                    Log.i(TAG, "FIM firebase");

                                }
                            }
                            listaDeletar.add(pavimentoIrregular);
                        }
                        listaIrregulares = null;
                    }

                    for(PavimentoIrregular deletar : listaDeletar){
                        db.pavimentoIrregularDAO().delete(deletar);
                    }
                }


                @Override
                public void onCancelled(DatabaseError databaseError) {
                }
            });
    }


    protected class TimerTaskToGetLocation extends TimerTask {

        private boolean doStop = false;
        private boolean executandoThread = false;

        public synchronized void doStop() {
            this.doStop = true;
        }

        public synchronized void doRun() {
            this.doStop = false;
        }

        private synchronized void setExecutandoThread(boolean executandoThread){
            this.executandoThread = executandoThread;
        }

        private synchronized boolean getExecutandoThread(){
            return this.executandoThread;
        }

        private synchronized boolean keepRunning() {
            return this.doStop == false;
        }
        @Override
        public void run() {
            while(keepRunning() && !getExecutandoThread()) {
                setExecutandoThread(true);
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        Log.e(TAG, "TimerTaskToGetLocation()");
                        enviarPavimentoIrregular();
                    }
                });
            }
        }
    }


}