package org.keyscience.app;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.view.ContextThemeWrapper;
import android.support.v7.view.menu.MenuBuilder;
import android.support.v7.view.menu.MenuPopupHelper;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;

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.Projection;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.maps.android.data.kml.KmlLayer;

import org.keyscience.R;
import org.keyscience.adapters.MapItemAdapter;
import org.xmlpull.v1.XmlPullParserException;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public class ReviewMapActivity extends AppCompatActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    private Toolbar toolbar;
    private FloatingActionButton floatingActionButton;

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

        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);

        // Retrieve the content view that renders the map.
        setContentView(R.layout.activity_record_map);
        // Get the SupportMapFragment and request notification
        // when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        setUpToolBar();

        floatingActionButton = findViewById(R.id.maps_action_button);

        final String map2016_2017 = "https://www.keyscience.org/wp-content/maps/map-2016-2017.kml";
        final String map2017_2018 = "https://www.keyscience.org/wp-content/maps/map-2017-2018.kml";
        final String map2018_2019 = "https://www.keyscience.org/wp-content/maps/map-2018-2019.kml";

        Context wrapper = new ContextThemeWrapper(ReviewMapActivity.this, R.style.PopUpMenuStyle);
        final PopupMenu popup = new PopupMenu(ReviewMapActivity.this, floatingActionButton);
        popup.inflate(R.menu.record_map_layers);
        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                resetIcons(popup);
                switch (menuItem.getItemId()) {
                    case R.id.layer_2016_2017:
                        menuItem.setIcon(R.drawable.ic_beaches_blue);
                        setMapLayer(mMap, map2016_2017);
                        return true;
                    case R.id.layer_2017_2018:
                        menuItem.setIcon(R.drawable.ic_coralreef_blue);
                        setMapLayer(mMap, map2017_2018);
                        return true;
                    case R.id.layer_2018_2019:
                        menuItem.setIcon(R.drawable.ic_greenareas_blue);
                        setMapLayer(mMap, map2018_2019);
                        return true;
                }
                return false;
            }
        });
        final MenuPopupHelper menuHelper = new MenuPopupHelper(wrapper, (MenuBuilder) popup.getMenu(), floatingActionButton);
        menuHelper.setForceShowIcon(true);
        menuHelper.setGravity(Gravity.END);

        floatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                menuHelper.show();
            }
        });

    }

    @Override
    public void onMapReady(final GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
        // Add a marker in KeyBiscayne and move the camera
        LatLng KeyBiscayne = new LatLng(25.700766, -80.157774);
        float zoom = 13;
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(KeyBiscayne, zoom));

        String url = "https://www.keyscience.org/wp-content/maps/map-2018-2019.kml";
        retrieveFileFromUrl(url);
    }

    private void setMapLayer(GoogleMap mMap, String layerFile) {
        mMap.clear();

        retrieveFileFromUrl(layerFile);
    }

    private void setUpToolBar() {
        // setup toolbar as action bar
        toolbar = findViewById(R.id.maps_toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setTitle(Constants.TITLE);
        toolbar.setSubtitle(Constants.CITIZEN_SCIENTIST_PROJECT);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_map_terrain, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.standard_map:
                mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                break;
            case R.id.hybrid_map:
                mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
                break;
            case R.id.satellite_map:
                mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
                break;
            case R.id.terrain_map:
                mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
                break;
        }

        return true;
    }

    public void resetIcons(PopupMenu popup) {
        popup.getMenu().findItem(R.id.layer_2016_2017).setIcon(R.drawable.ic_beaches);
        popup.getMenu().findItem(R.id.layer_2017_2018).setIcon(R.drawable.ic_coralreef);
        popup.getMenu().findItem(R.id.layer_2018_2019).setIcon(R.drawable.ic_greenareas);
    }

    private void retrieveFileFromUrl(String url) {
        new LoadKmlAsync(url).execute();
    }

    private class LoadKmlAsync extends AsyncTask<String, Void, byte[]> {
        private final String mUrl;

        public LoadKmlAsync(String url) {
            mUrl = url;
        }

        protected byte[] doInBackground(String... params) {
            try {
                InputStream is = new URL(mUrl).openStream();
                ByteArrayOutputStream buffer = new ByteArrayOutputStream();
                int nRead;
                byte[] data = new byte[16384];
                while ((nRead = is.read(data, 0, data.length)) != -1) {
                    buffer.write(data, 0, nRead);
                }
                buffer.flush();
                return buffer.toByteArray();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        protected void onPostExecute(byte[] byteArr) {
            try {

                KmlLayer kmlLayer = new KmlLayer(mMap, new ByteArrayInputStream(byteArr),
                        getApplicationContext());
                kmlLayer.addLayerToMap();
                kmlLayer.setMap(mMap);

                mMap.setInfoWindowAdapter(new MapItemAdapter(getApplicationContext()));

                mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
                    @Override
                    public boolean onMarkerClick(Marker marker) {
                //        Toast.makeText(getApplicationContext(), "Marker Clicked", Toast.LENGTH_SHORT).show();

                        DisplayMetrics metrics;
                        metrics = Resources.getSystem().getDisplayMetrics();

                        Projection projection = mMap.getProjection();
                        LatLng markerPosition = marker.getPosition();
                        Point markerPoint = projection.toScreenLocation(markerPosition);
                        Point targetPoint = new Point(markerPoint.x, markerPoint.y - (metrics.heightPixels / 3) - 200 );
                        LatLng targetPosition = projection.fromScreenLocation(targetPoint);
                        mMap.animateCamera(CameraUpdateFactory.newLatLng(targetPosition), 1000, null);

                        marker.showInfoWindow();

                        return true;
                    }
                });

                mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
                    @Override
                    public void onInfoWindowClick(Marker marker) {
                        marker.hideInfoWindow();
                    }
                });

            } catch (XmlPullParserException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
