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.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
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.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

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

import com.google.android.gms.maps.model.LatLng;
import com.google.maps.android.SphericalUtil;


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

public class FragmentDistances extends Fragment {

    private LinearLayout mainView;
    ArrayAdapter<City> cityAdapter;
    TextView currentLocView;

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

    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);
        doLayout();
    }



    private void doLayout() {
        mainView.removeAllViews();
        final float density = getResources().getDisplayMetrics().density;

        currentLocView = new TextView(getContext());
        currentLocView.setPadding((int)(3*density), (int)(5*density), 0, (int)(5*density));
        currentLocView.setGravity(Gravity.CENTER);
        currentLocView.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.teal_700));
        currentLocView.setTextColor(Color.WHITE);
        currentLocView.setTypeface(null, Typeface.BOLD);
        mainView.addView(currentLocView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));

        ListView theLv = new ListView(getContext());
        mainView.addView(theLv, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 9));
        theLv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        theLv.setBackgroundColor(Color.rgb(240, 240, 240));
        theLv.setDivider(new ColorDrawable(0xff8B008B));
        theLv.setDividerHeight((int)(2*getResources().getDisplayMetrics().density));
        theLv.setStackFromBottom(true);
        theLv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
        cityAdapter = new ArrayAdapter<City>(getContext(), 0, DataCities.getInstance().getCities())
        {

            @NonNull
            @SuppressLint("InflateParams")
            @Override
            public View getView(int position, View convertView, @NonNull ViewGroup parent)
            {
                View view = convertView;
                if (view == null)
                {
                    view = new LinearLayout(getContext());
                }
                City msg = this.getItem(position);
                LinearLayout ll = (LinearLayout) view;
                ll.removeAllViews();
                ll.setOrientation(LinearLayout.HORIZONTAL);
                ll.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
                {
                    TextView tv = new TextView(getContext());
                    tv.setText(msg.name + " " + msg.state);
                    tv.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
                    tv.setPadding((int)(3*density), (int)(8*density), 0, (int)(8*density));
                    ll.addView(tv, new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 3));
                }
                {
                    TextView tv = new TextView(getContext());
                    tv.setText(String.format("%8.2f km", msg.getDistance()/1000));
                    tv.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
                    float density = getResources().getDisplayMetrics().density;
                    tv.setPadding((int)(3*density), (int)(8*density), 0, (int)(8*density));
                    ll.addView(tv, new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1));
                }
                return view;
            }

        };
        theLv.setAdapter(cityAdapter);
    }

    public static Double distanceBetween(LatLng point1, LatLng point2) {
        if (point1 == null || point2 == null) {
            return null;
        }
        return SphericalUtil.computeDistanceBetween(point1, point2);
    }

    private class MyLocationListener implements LocationListener {
        @Override
        public void onLocationChanged(Location loc) {
            MainActivity.currentLocation=loc;
            /*------- 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) {
                    cityName = addresses.get(0).getLocality();
                }
                currentLocView.setText(String.format("Current Location: Lat:%6.2f Long:%6.2f\n%s, %s", loc.getLatitude(), loc.getLongitude(), cityName, addresses.get(0).getAdminArea()));
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            LatLng ll = new LatLng(loc.getLatitude(), loc.getLongitude());
            for (City c : DataCities.getInstance().getCities()) {
                c.setDistanceFrom(ll);
            }
            DataCities.getInstance().sortByDistance();
            cityAdapter.notifyDataSetChanged();
        }

        @Override
        public void onProviderDisabled(String provider) {}

        @Override
        public void onProviderEnabled(String provider) {}

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

}
