package edu.brynmawr.ple2;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
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.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.PolygonOptions;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class FragmentLocation extends Fragment implements OnMapReadyCallback, GoogleMap.OnMyLocationButtonClickListener,
        GoogleMap.OnMyLocationClickListener {

    private LinearLayout mainView;
    TextView tv;
    MapView mapView;
    GoogleMap googleMap;
    Location lastLoc=null; // every time you move this gets changed
    ArrayList<LatLng> polyPoints = new ArrayList<>();

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // set up the initial layout
        LinearLayout ll = new LinearLayout(getContext());
        ll.setId(View.generateViewId());
        ll.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        ll.setBackgroundColor(Color.WHITE);
        ll.setOrientation(LinearLayout.VERTICAL);

        mainView = ll;
        return ll;

    }

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        //layoutDoLocation();
        LocationManager locationManager = (LocationManager)
                getContext().getSystemService(Context.LOCATION_SERVICE);


        LocationListener locationListener = new MyLocationListener();
        if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
                    Manifest.permission.ACCESS_FINE_LOCATION)) {
                Toast.makeText(getContext(), "The app needs to access your location to do things with the map", Toast.LENGTH_LONG).show();
            } else {
                // No explanation needed; request the permission
                ActivityCompat.requestPermissions(getActivity(),
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        1476);
            }
            return;
        }
        locationManager.requestLocationUpdates(
                LocationManager.GPS_PROVIDER, 20, 10, locationListener);

        //ActionBar actionBar = ((AppCompatActivity)getContext()).getSupportActionBar();
        //actionBar.hide();
        layoutMap(savedInstanceState);
    }




    @SuppressLint("SetTextI18n")
    private void layoutMap(Bundle savedInstanceState) {
        mapView = new MapView(getContext());
        mainView.addView(mapView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0,9));

        mapView.onCreate(savedInstanceState);

        mapView.onResume(); // needed to get the map to display immediately

        try {
            MapsInitializer.initialize(getActivity().getApplicationContext());
        } catch (Exception e) {
            e.printStackTrace();
        }
        mapView.getMapAsync(this);

        tv = new TextView(getContext());
        tv.setText("Welcome to the PLE app. Location!!");
        tv.setGravity(Gravity.CENTER);
        tv.setPadding((int)(10*getResources().getDisplayMetrics().density), 0, (int)(10*getResources().getDisplayMetrics().density), 0);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1);
        mainView.addView(tv, lp);

    }


    @SuppressLint("SetTextI18n")
    private void layoutDoLocation() {
        mainView.setBackgroundColor(Color.rgb(25, 255, 240));
        tv = new TextView(getContext());
        tv.setText("Welcome to the PLE app. Location!!");
        tv.setGravity(Gravity.CENTER);
        tv.setPadding((int)(10*getResources().getDisplayMetrics().density), 0, (int)(10*getResources().getDisplayMetrics().density), 0);
        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        mainView.addView(tv, lp);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        Log.i("THISS", "Got map callback 2");
        //googleMap = gMap;

        if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
         && ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
         return;
         }
        try
        {
            googleMap.setMyLocationEnabled(true);
            googleMap.setOnMyLocationButtonClickListener(this);
            googleMap.setOnMyLocationClickListener(this);
            googleMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
                @Override
                public void onMapClick(LatLng latLng) {
                    Log.i("THISS", "Clicked at " + latLng);
                    polyPoints.add(latLng);
                    Log.i("THISS", "BBBB" + polyPoints.size());
                    if (polyPoints.size()>3) {
                        PolygonOptions po = new PolygonOptions()
                                .clickable(true);
                        for (LatLng ll : polyPoints)
                            po.add(ll);
                        Polygon polygon1 = googleMap.addPolygon(po);
                        polygon1.setTag("alpha");
                        polygon1.setFillColor(Color.argb(128, 128, 128,0));
                        Log.i("THISS", "Added a polygon");
                        polyPoints.clear();
                    }
                }
            });
        }
        catch (Exception ee)
        {
            Log.e("KIKL", "Problematic " + ee.toString());
            ee.printStackTrace();
        }

        googleMap.getUiSettings().setZoomControlsEnabled(true);


        LatLng mCurrentLocation = getLocation();
        if (mCurrentLocation==null)
        {
            mCurrentLocation = new LatLng(39.92, -75.63);
        }
        this.googleMap=googleMap;
        zoomMap(mCurrentLocation);

        Log.i("THISS", "AAA"+DataCities.getInstance());
        for (City c : DataCities.getInstance().getCities()) {
            MarkerOptions markerOptions = new MarkerOptions();
            markerOptions.position(new LatLng(c.getLatitude(), c.getLongitude()));
            markerOptions.title(c.name);
            markerOptions.snippet(c.state);

            Marker m = googleMap.addMarker(markerOptions);
            m.setTag("PIN");
        }

    }

    private void zoomMap(LatLng zoomOn)
    {
        if (zoomOn==null)
            return;
        CameraPosition cameraPosition;
        cameraPosition = new CameraPosition.Builder().target(zoomOn).zoom(12).build();
        googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
    }


    public LatLng getLocation() {
        if (lastLoc != null) {
            return new LatLng(lastLoc.getLatitude(), lastLoc.getLongitude());
        } else {
            Toast.makeText(getContext(), "Could not get longitude/latitude" , Toast.LENGTH_SHORT).show();
        }
        return null;
    }


    @Override
    public boolean onMyLocationButtonClick() {
        Log.i("THISS", "location button click ");
        return false;
    }

    @SuppressLint("SetTextI18n")
    @Override
    public void onMyLocationClick(@NonNull Location location) {
        Log.i("THISS", "Current location:\n" + location);
        if (tv!=null)
            tv.setText("Loc: " + location);
        LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
        zoomMap(ll);
    }

    private class MyLocationListener implements LocationListener {
        @Override
        public void onLocationChanged(Location loc) {
            MainActivity.currentLocation=loc;
            if (tv!=null)
                tv.setText("");
            String longitude = "Longitude: " + loc.getLongitude();
            String latitude = "Latitude: " + loc.getLatitude();

            /*------- To get city name from coordinates -------- */
            String cityName = null;
            Geocoder gcd = new Geocoder(getContext(), Locale.getDefault());
            List<Address> addresses;
            try {
                addresses = gcd.getFromLocation(loc.getLatitude(),
                        loc.getLongitude(), 1);
                if (addresses.size() > 0) {
                    System.out.println(addresses.get(0).getLocality());
                    cityName = addresses.get(0).getLocality();
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            String s = longitude + "\n" + latitude + "\n\nMy Current City is: "
                    + cityName;
            if (lastLoc!=null) {
                float dist = loc.distanceTo(lastLoc);
                s = s + " Moved:" + dist;
            }
            if (tv!=null)
                tv.setText(s);
            lastLoc=loc;
            if (googleMap!=null)
                zoomMap(getLocation());
        }

        @Override
        public void onProviderDisabled(String provider) {}

        @Override
        public void onProviderEnabled(String provider) {}

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    }
}
