package br.com.minhavia.minhavia.view;

import android.Manifest;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.util.Log;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.TileOverlay;
import com.google.android.gms.maps.model.TileOverlayOptions;
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 com.google.maps.android.heatmaps.Gradient;
import com.google.maps.android.heatmaps.HeatmapTileProvider;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import br.com.minhavia.minhavia.R;
import br.com.minhavia.minhavia.firebase.PavimentoIrregularFirebase;
import br.com.minhavia.minhavia.model.DadosFirebase;
import br.com.minhavia.minhavia.receive.AlarmFirebaseReceive;
import br.com.minhavia.minhavia.receive.AlarmGeoReceive;
import br.com.minhavia.minhavia.receive.AlarmReceive;
import br.com.minhavia.minhavia.util.Constantes;

public class MapaActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener {

    private GoogleMap mMap;
    private LocationManager locationManager;
    private double latitude = -19.841644;
    private double longitude = -43.986511;

    private Map<String, List<LatLng>> mapLatLng = new HashMap<String, List<LatLng>>();
    private DatabaseReference pavimentoIrregularFirebase;
    private HeatmapTileProvider mProvider;
    private TileOverlay mOverlay;
    private Gradient gradient;
    private List<LatLng> listaLatLong = new ArrayList<>();
    private int[] colors = {
            Color.rgb(102, 225, 0), // green
            Color.rgb(255, 0, 0)    // red
    };

    private float[] startPoints = {
            0.3f, 1f
    };


    AlarmManager alarmManager;
    PendingIntent pendingIntent;

    AlarmManager alarmManagerFirebase;
    PendingIntent pendingIntentFirebase;

    AlarmManager alarmManagerGeo;
    PendingIntent pendingIntentGeo;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mapa);

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 200);
            return;
        }
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);

        if (alarmManager == null) {
            alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            Intent intent = new Intent(this, AlarmReceive.class);
            pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), Constantes.TIMER_REPEAT_LOCATION,
                    pendingIntent);
        }

        if (alarmManagerFirebase == null) {
            alarmManagerFirebase = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            Intent intent = new Intent(this, AlarmFirebaseReceive.class);
            pendingIntentFirebase = PendingIntent.getBroadcast(this, 0, intent, 0);
            alarmManagerFirebase.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), Constantes.TIMER_REPEAT_FIREBASE,
                    pendingIntentFirebase);
        }


        if (alarmManagerGeo == null) {
            alarmManagerGeo = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            Intent intent = new Intent(this, AlarmGeoReceive.class);
            pendingIntentGeo = PendingIntent.getBroadcast(this, 0, intent, 0);
            alarmManagerGeo.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), Constantes.TIMER_REPEAT_GEO,
                    pendingIntentGeo);
        }

        pavimentoIrregularFirebase = PavimentoIrregularFirebase.getFirebaseDatabase();

        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }


    @Override
    public void onMapReady(GoogleMap googleMap) {
        listaLatLong = new ArrayList<>();
        readItems();
        mMap = googleMap;

        gradient = new Gradient(colors, startPoints);

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        mMap.setMyLocationEnabled(true);

        LatLng loc = new LatLng(latitude, longitude);
        mMap.moveCamera(CameraUpdateFactory.newLatLng(loc));
        // Zoom in, animating the camera.
        mMap.animateCamera(CameraUpdateFactory.zoomIn());

// Zoom out to zoom level 10, animating with a duration of 2 seconds.
        mMap.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);

    }

    private void readItems() {
        pavimentoIrregularFirebase.child("pais").child("BR").child("uf").child("Minas Gerais").addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                listaLatLong = new ArrayList<>();


                for (DataSnapshot dados : dataSnapshot.getChildren()) {
                    for (DataSnapshot dadosCidade : dados.getChildren()) {
                        for (DataSnapshot dadosNomeCidade : dadosCidade.getChildren()) {
                            for (DataSnapshot dadosLogradouro : dadosNomeCidade.getChildren()) {
                                for (DataSnapshot dadosPontoLogradouro : dadosLogradouro.getChildren()) {
                                    DadosFirebase dadosFirebase = dadosPontoLogradouro.getValue(DadosFirebase.class);
                                    LatLng latLng = new LatLng(Double.parseDouble(dadosFirebase.getLatitude()), Double.parseDouble(dadosFirebase.getLongitude()));
                                    listaLatLong.add(latLng);
                                }
                            }
                        }
                    }
                }

                gradient = new Gradient(colors, startPoints);

                // Create the tile provider.
                mProvider = new HeatmapTileProvider.Builder()
                        .data(listaLatLong)
                        .gradient(gradient)
                        .build();

                mOverlay = mMap.addTileOverlay(new TileOverlayOptions().tileProvider(mProvider));
                mProvider.setOpacity(0.7);
                mOverlay.clearTileCache();

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }

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

    private String getLocation() {
        String locations = "{\"locations\": []}";
        /*
        try {
        File f = FileUtils.getFile(getContext(), NOME_ARQUIVO);
        locations = IOUtils.readString(f);
            locations = locations != null && locations.length() > 0 ? "{\"locations\": [" + locations.substring(1) + "]}" : "{\"locations\": []}";
        }catch(Exception e){
            return "";
        }*/
        return locations;
    }

    private Context getContext() {
        return this;
    }

    @Override
    public void onLocationChanged(Location location) {
        latitude = location.getLatitude();
        longitude = location.getLongitude();


    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {

    }

    @Override
    public void onProviderEnabled(String s) {

    }

    @Override
    public void onProviderDisabled(String s) {

    }
}
