package org.linphone.bluereach;

import android.Manifest;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;

import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesRepairableException;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.places.AutocompleteFilter;
import com.google.android.gms.location.places.Place;
import com.google.android.gms.location.places.ui.PlaceAutocomplete;
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.OnMapReadyCallback;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
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 org.linphone.R;
import org.linphone.services.PlayLocation;
import org.linphone.utils.AppIntegers;
import org.linphone.utils.AppMethods;
import org.linphone.utils.AppStrings;
import org.linphone.utils.SessionManager;

import java.util.List;
import java.util.Locale;

public class Location extends AppCompatActivity implements  View.OnClickListener {
    private static final String TAG = "Location";
    SessionManager sessionManager;
    String latitude = "0.0", longitude = "0.0";
    ImageView location_save_iv;
    Geocoder geocoder;
    String dragLat_string, dragLong_string;
    double fromlatitude, fromlongitude;
    int LOCATION_REQUEST_CODE = 100;
    TextView seach_map_tv, location_title_tv;
    int PLACE_AUTOCOMPLETE_REQUEST_CODE = 1;
    ImageView location_back_iv, clear_address_iv;
    String maddress = "", mcity = "", mstate = "", mzip_code = "", mcountry = "", mAdminArea = "";
    ;
    String lat_extra = "", long_Extra = "", location_status = "";
    String toolbar_titile;
    ProgressDialog pd;
    MapView map_pins_mapview;
    String mSubAdminArea = "", mLocality = "", mSubLocality = "", mThoroughfare = "", mSubThoroughfare = "", mCountryName = "";
    RelativeLayout search_rl;
    Intent intent;
    private GoogleMap mMap;
    int LOCATION_PERMISSION_REQUEST_CODE=1;

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

        init();
    }

    public void initMap(Bundle savedInstanceState) {
        map_pins_mapview = (MapView) findViewById(R.id.map_pins_mapview);
        map_pins_mapview.onCreate(savedInstanceState);
        map_pins_mapview.onResume();// needed to get the map to display immediately
        map_pins_mapview.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap googleMap) {
                mMap = googleMap;

                onReadyMap();
            }
        });
    }


    public void init() {
        sessionManager = new SessionManager(Location.this);
        location_title_tv = (TextView) findViewById(R.id.location_title_tv);
        search_rl = (RelativeLayout) findViewById(R.id.search_rl);
         intent = getIntent();
        if (intent != null) {
            lat_extra = intent.getStringExtra(AppStrings.IntentData.latitude);
            long_Extra = intent.getStringExtra(AppStrings.IntentData.longitude);
        } else {
            lat_extra = String.valueOf(PlayLocation.playlat);
            long_Extra = String.valueOf(PlayLocation.playlog);
        }

//            location_title_tv.setText(R.string.select_location);
        search_rl.setVisibility(View.VISIBLE);




        seach_map_tv = (TextView) findViewById(R.id.seach_map_tv);
        clear_address_iv = (ImageView) findViewById(R.id.clear_address_iv);
        location_back_iv = (ImageView) findViewById(R.id.location_back_iv);
        location_save_iv = (ImageView) findViewById(R.id.location_save_iv);
        location_save_iv.setOnClickListener(this);
        location_back_iv.setOnClickListener(this);
        clear_address_iv.setOnClickListener(this);
        seach_map_tv.setOnClickListener(this);


        location_save_iv.setVisibility(View.VISIBLE);


        clear_address_iv.setVisibility(View.GONE);
        seach_map_tv.setClickable(true);
        clear_address_iv.setVisibility(View.VISIBLE);
    }



    public void onReadyMap() {
        //        mMap = googleMap;


        double lat = 0;
        double lon = 0;
        try {

            lat = Double.parseDouble(lat_extra);
            lon = Double.parseDouble(long_Extra);
            latitude = String.valueOf(lat);
            longitude = String.valueOf(lon);


        } catch (NumberFormatException e) {
            e.printStackTrace();
        }

        setMapLocation(lat,lon,true);
        if (mMap != null &&
                findViewById(Integer.parseInt("1")) != null) {
            // Get the button view
            View locationButton = ((View) findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
            // and next place it, on bottom right (as Google Maps app)
            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)
                    locationButton.getLayoutParams();
            // position on right bottom
            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
            layoutParams.setMargins(0, 0, 30, 30);
//            layoutParams.addRule(RelativeLayout.ABOVE, 14);

        }
        enableMyLocationIfPermitted();




        // Add a marker in Sydney and move the camera
        setAddress(lat,lon);

        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lon), AppIntegers.MAP_ZOOM));
        mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {


                return false;
            }

        });

        //add location button click listener
        mMap.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener(){
            @Override
            public boolean onMyLocationButtonClick()
            {
                //TODO: Any custom actions

                maddress = "";
                mstate = "";
                mzip_code = "";
                mcountry = "";
                mcity = "";
                mMap.clear();
                latitude = String.valueOf(PlayLocation.playlat);
                longitude = String.valueOf(PlayLocation.playlog);

                setMapLocation(PlayLocation.playlat,PlayLocation.playlog,true);
                setAddress(PlayLocation.playlat,PlayLocation.playlog);
                return true;
            }
        });
        mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                maddress = "";
                mstate = "";
                mzip_code = "";
                mcountry = "";
                mcity = "";

                // Creating a marker
                MarkerOptions markerOptions = new MarkerOptions();


                seach_map_tv.setText(getString(R.string.search_google_maps));
                latitude = String.valueOf(latLng.latitude);
                longitude = String.valueOf(latLng.longitude);


                double dragLat = latLng.latitude;
                double dragLong = latLng.longitude;
                // Setting the position for the marker
                markerOptions.position(latLng).icon(BitmapDescriptorFactory.fromResource(R.mipmap.locat));

                // Setting the title for the marker.

                mMap.clear();

                // Animating to the touched position
                mMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));

                // Placing a marker on the touched position
                mMap.addMarker(markerOptions);

                setAddress(latLng.latitude,latLng.longitude);


            }
        });

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {


            case R.id.location_back_iv:

                finish();
                break;

            case R.id.location_save_iv:
                sendLatLongs();
                break;

            case R.id.seach_map_tv:
                findPlace();
                break;
            case R.id.clear_address_iv:
//                seach_map_tv.setText("");

                findPlace();
                break;
        }
    }


    /*checking google places*/
    public void findPlace() {

        AutocompleteFilter typeFilter = new AutocompleteFilter.Builder()
                .setTypeFilter(AutocompleteFilter.TYPE_FILTER_NONE)
                .build();
        try {
            Intent intent = new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_FULLSCREEN)
                    .setFilter(typeFilter)
                    .build(Location.this);
            startActivityForResult(intent, PLACE_AUTOCOMPLETE_REQUEST_CODE);
        } catch (GooglePlayServicesRepairableException e) {
            // TODO: Handle the error.
        } catch (GooglePlayServicesNotAvailableException e) {
            // TODO: Handle the error.
        }
    }


    public void sendLatLongs() {

        if (latitude.equals("0.0") && longitude.equals("0.0")) {
            AppMethods.showToast(Location.this, getString(R.string.select_location));
        } else {

            Intent intent = new Intent();
            intent.putExtra(AppStrings.Location.myaddress, maddress);
            intent.putExtra(AppStrings.Location.mcity, mcity);
            intent.putExtra(AppStrings.Location.mcountry, mcountry);
            intent.putExtra(AppStrings.Location.mzip_code, mzip_code);
            intent.putExtra(AppStrings.Location.mstate, mstate);
            intent.putExtra(AppStrings.Location.latitude_intent, latitude);
            intent.putExtra(AppStrings.Location.longitude_intent, longitude);

            setResult(AppIntegers.SET_LOCATION_REQUEST_CODE, intent);

            finish();


        }


    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK) {
            if (requestCode == PLACE_AUTOCOMPLETE_REQUEST_CODE) {


                Place place = PlaceAutocomplete.getPlace(this, data);

                //   sending address here
                String[] separated = place.getLatLng().toString().split(",");


                seach_map_tv.setText("" + place.getAddress());

                maddress = "" + place.getAddress();

                double lat = Double.parseDouble(String.valueOf(separated[0]).replace("lat/lng: (", ""));
                double lon = Double.parseDouble(String.valueOf(separated[1]).replace(")", ""));


                latitude = String.valueOf(lat);
                longitude = String.valueOf(lon);

                mMap.clear();
                LatLng local_location = new LatLng(lat, lon);

                mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lon), AppIntegers.MAP_ZOOM));
                // Animating to the touched position

                MarkerOptions markerOptions = new MarkerOptions();

//                markerOptions.position(local_location).icon(BitmapDescriptorFactory.fromResource(R.mipmap.location_iv));
                mMap.animateCamera(CameraUpdateFactory.newLatLng(local_location));

                // Placing a marker on the touched position
//                mMap.addMarker(markerOptions);

                mMap.addMarker(new MarkerOptions().position(local_location).icon(BitmapDescriptorFactory.fromResource(R.mipmap.locat)));

            }

        } else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
            Status status = PlaceAutocomplete.getStatus(this, data);
            // TODO: Handle the error.
            Log.i(TAG, status.getStatusMessage());

        } else if (resultCode == RESULT_CANCELED) {
            // The user canceled the operation.
        }

    }
    private void enableMyLocationIfPermitted() {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
                            Manifest.permission.ACCESS_FINE_LOCATION},
                    LOCATION_PERMISSION_REQUEST_CODE);
        } else if (mMap != null) {

//            mMap.clear();
            mMap.setMyLocationEnabled(true);

//            mMap.getUiSettings().setMyLocationButtonEnabled(false);
//            mMap.set
        }
    }

    private void setMapLocation(double lat,double lon,boolean map_status) {
        if(map_status){
            mMap.clear();
        }

        LatLng local_location = new LatLng(lat, lon);
        mMap.addMarker(new MarkerOptions().position(local_location).icon(BitmapDescriptorFactory.fromResource(R.mipmap.locat)).title(getString(R.string.app_name)));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(local_location));

    }
    public void setAddress(double lat,double lon){
        if (lat == 0 || lon == 0) {
        } else {


            try {
                Geocoder geocoder = new Geocoder(Location.this, Locale.getDefault());

                List<Address> addresses = geocoder.getFromLocation(lat, lon, 1);
                String address = addresses.get(0).getAddressLine(0); // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
                String city = addresses.get(0).getLocality();
                String state = addresses.get(0).getAdminArea();
                String zip = addresses.get(0).getPostalCode();
                String country = addresses.get(0).getCountryName();
                maddress = "";
                mstate = "";
                mzip_code = "";
                mcountry = "";
                mcity = "";

                maddress = address + "," + city;
                mstate = state;
                mzip_code = zip;
                mcountry = country;
                mcity = city;


                try {
                    seach_map_tv.setText(maddress);
                } catch (Exception e) {
                    e.printStackTrace();
                }


            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

}
