package com.app.simplitend.cg_geofencing;

import static com.app.simplitend.patientgeofencing.PatientLocationUpdatesReceiver.LOCATION_REQUEST_TAG;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;

import com.app.simplitend.R;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.apputils.CaregiverDataCache;
import com.app.simplitend.caregiverdashboard.mvvm.CaregiverMainViewModel;
import com.app.simplitend.caregiverdashboard.mvvm.CgHomeContracts;
import com.app.simplitend.caregiverdashboard.mvvm.models.GeoFenceDetails;
import com.app.simplitend.databinding.ActivityCgGeofencingBinding;
import com.app.simplitend.databinding.GeofenceBottomSheetBinding;
import com.app.simplitend.chats.SocketHelper;
import com.app.simplitend.welcome.welcomecg.mvvm.CareGiverData;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.PatientData;
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.Circle;
import com.google.android.gms.maps.model.CircleOptions;
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.libraries.places.api.Places;
import com.google.android.libraries.places.api.model.Place;
import com.google.android.libraries.places.widget.Autocomplete;
import com.google.android.libraries.places.widget.model.AutocompleteActivityMode;
import com.google.android.material.bottomsheet.BottomSheetDialog;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

public class CgGeoFencingActivity extends AppCompatActivity implements OnMapReadyCallback,
        CgHomeContracts.SaveGeoFenceCallback, CgHomeContracts.UpdatePatientAddressCallback {

    private static final String TAG = "CgGeoFencingActivity";

    // view binding
    protected ActivityCgGeofencingBinding binding;

    private CaregiverMainViewModel viewModel;

    public static final String GEOFENCE_DETAILS_KEY = "geofence_details";
    private GeoFenceDetails geoFenceDetails;

    private static final String MILES = "miles";
    private static final String KMS = "kms";

    // bottom sheet binding
    private BottomSheetDialog bottomSheetDialog;

    private GeofenceBottomSheetBinding geofence_bs_binding;

    private CareGiverData careGiverData;
    private PatientData patientData;

    private GoogleMap mMap;

    private LatLng mHomeLatLng, pat_cur_latLng;

    private ActivityResultLauncher<Intent> startAutocompleteMapSearch;

    private ProgressDialog progressDialog;
    private Marker curr_loc_marker;
    private Marker home_loc_marker;

    private Circle radius_circle;

    private boolean isTrackingSenior;

    private String selectedStreet;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityCgGeofencingBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        Intent intent = getIntent();

        if (intent != null && intent.hasExtra(GEOFENCE_DETAILS_KEY)) {
            try {
                geoFenceDetails = (GeoFenceDetails) intent.getSerializableExtra(GEOFENCE_DETAILS_KEY);
                if (geoFenceDetails == null) throw new Exception();

                try {
                    pat_cur_latLng = new LatLng(Double.parseDouble(geoFenceDetails.patient_radius_location.lat),
                            Double.parseDouble(geoFenceDetails.patient_radius_location.lng));
                } catch (Exception e) {
                    pat_cur_latLng = null;
                }
            } catch (Exception e) {
                Toast.makeText(this, "Couldn't load Geofence.", Toast.LENGTH_SHORT).show();
                geoFenceDetails = new GeoFenceDetails();
                onBackPressed();
                return;
            }
        } else {
            onBackPressed();
            return;
        }

        viewModel = new ViewModelProvider(this).get(CaregiverMainViewModel.class);
        progressDialog = new ProgressDialog(this);

        geofence_bs_binding = GeofenceBottomSheetBinding.inflate(getLayoutInflater());
        geofence_bs_binding.unitSpinner.selectItemByIndex(1);
        isTrackingSenior = false;

        CaregiverDataCache.getCaregiverData(this, (careGiverData -> {
            if (careGiverData == null) return;

            this.careGiverData = careGiverData;
            this.patientData = careGiverData.patientDetails;
        }), true);

        initViews();

        initBottomSheet();

        clickEvents();

        updatePatientCurrentLocationDetails();

        establishSocketConnection();

    }

    @Override
    protected void attachBaseContext(Context newBase) {
        final Configuration configuration = new Configuration(newBase.getResources().getConfiguration());
        configuration.fontScale = Math.min(configuration.fontScale, 1.1f);
        applyOverrideConfiguration(configuration);
        super.attachBaseContext(newBase);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (careGiverData != null) {
            SocketHelper.getInstance().removeLocationUpdateListener(careGiverData.patientId + "");
        }

//        SocketHelper.getInstance().closeConnection();
    }

    private void establishSocketConnection() {
        CaregiverDataCache.getCaregiverData(this, (careGiverData1 -> {
            if (careGiverData1 != null) {
                this.careGiverData = careGiverData1;

                SocketHelper socketHelper = SocketHelper.getInstance();
                socketHelper.establishConnection(null);

                Log.d(LOCATION_REQUEST_TAG, "CG STARTED LISTENING TO LOCATION UPDATES");
                socketHelper.getLocationUpdates(careGiverData1.patientId + "", new SocketHelper.Callback<Location>() {
                    @Override
                    public void onMessageReceived(Location result) {
                        Log.d(LOCATION_REQUEST_TAG, "LOCATION RECEIVED: " + result);
                        if (result != null) {
                            // running on main thread
                            new Handler(Looper.getMainLooper()).post(() -> {
                                pat_cur_latLng = new LatLng(result.getLatitude(), result.getLongitude());
                                updateCurrentLocationPatientMarker();
                                updatePatientCurrentLocationDetails();
                            });
                        }
                    }

                    @Override
                    public void onMessageSentSuccessfully() {

                    }

                    @Override
                    public void onError(Exception e) {
                        Log.e(LOCATION_REQUEST_TAG, "CG LISTENING TO LOCATION UPDATES", e);
                    }
                });
            }
        }), false);
    }

    private void initBottomSheet() {

        bottomSheetDialog = new BottomSheetDialog(this, R.style.BottomSheetDialog);
        bottomSheetDialog.setContentView(geofence_bs_binding.getRoot());
        bottomSheetDialog.setCancelable(true);

        if (geoFenceDetails == null) return;

        float radius = 0.0f;
        if (geoFenceDetails.radius != null) {
            try {
                radius = Float.parseFloat(geoFenceDetails.radius);
            } catch (Exception e) {
                // do nothing
            }
        }

        if (geoFenceDetails.type == null) {
            // default
            geofence_bs_binding.unitSpinner.selectItemByIndex(1);
        } else if (MILES.equals(geoFenceDetails.type)) {
            geofence_bs_binding.unitSpinner.selectItemByIndex(1);
            radius = radius / 1609.34f;
        } else {
            geofence_bs_binding.unitSpinner.selectItemByIndex(0);
            radius = radius / 1000f;
        }

        geofence_bs_binding.unitSpinner.setLifecycleOwner(this);
        geofence_bs_binding.unitSpinner.setIsFocusable(true);

        if (radius != 0) {
            geofence_bs_binding.radius.setText("" + radius);
        }
        geofence_bs_binding.message.setText(geoFenceDetails.message);
    }

    private void initViews() {
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.geofence_map);
        if (mapFragment != null) {
            mapFragment.getMapAsync(this);
        } else {
            Toast.makeText(this, "Couldn't load map. Please try again.", Toast.LENGTH_SHORT).show();
        }

        registerMapSearchResultLauncher();
    }

    private void clickEvents() {
        binding.backBtn.setOnClickListener(v -> onBackPressed());

        binding.changeBtn.setOnClickListener(v -> {
            if (binding.search.getVisibility() == View.VISIBLE) {
                binding.search.setVisibility(View.GONE);
                binding.changeBtn.setText(getString(R.string.change));
            } else {
                binding.changeBtn.setText(getString(R.string.close_));
                binding.search.setVisibility(View.VISIBLE);
            }
        });

        binding.setGf.setOnClickListener(v -> {
            if (bottomSheetDialog != null) {
                bottomSheetDialog.show();
            }
        });

        geofence_bs_binding.save.setOnClickListener(v -> {
            saveGeoFence();
        });

        geofence_bs_binding.cancelSetGf.setOnClickListener(v -> {
            if (bottomSheetDialog != null) {
                bottomSheetDialog.dismiss();
            }
        });

        binding.search.setOnClickListener(v -> {

            List<Place.Field> fields = Arrays.asList(Place.Field.ID, Place.Field.NAME, Place.Field.LAT_LNG);

            Intent intent = new Autocomplete.IntentBuilder(AutocompleteActivityMode.OVERLAY, fields)
                    .setHint(getString(R.string.enter_new_address_here))
                    .build(this);

            startAutocompleteMapSearch.launch(intent);
        });

        binding.resetBtn.setOnClickListener(v -> {
            loadPatientsLocation();
            binding.updateBtnsView.setVisibility(View.GONE);
            binding.homeLocationBtn.setVisibility(View.VISIBLE);
            binding.cgLocationBtn.setVisibility(View.VISIBLE);
        });

        binding.updateBtn.setOnClickListener(v -> {
            if (careGiverData != null) {
                AppUtil.showAlert(this,
                        "Update senior's geofence",
                        "Are you sure you want to update the location?\nSenior Geofence will be updated.",
                        getString(R.string.ok), ((dialogInterface, i) -> {
                            updatePatientAddress();
                        }),
                        "Cancel", ((dialogInterface, i) -> {
                        }));
            } else {
                Toast.makeText(this, "Cannot update address.", Toast.LENGTH_SHORT).show();
            }
        });

        binding.homeLocationBtn.setOnClickListener(v -> {
            if (mMap != null && home_loc_marker != null) {
                mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(home_loc_marker.getPosition(), 16));
                isTrackingSenior = false;
            }
        });

        binding.cgLocationBtn.setOnClickListener(v -> {
            if (mMap != null && curr_loc_marker != null) {
                mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(curr_loc_marker.getPosition(), 16));
                isTrackingSenior = true;
            }
        });
    }

    private void updatePatientCurrentLocationDetails() {
        if (patientData == null) return;

        try {
            if (pat_cur_latLng != null) {
                // calculating distance
                LatLng homeLatLng = new LatLng(Double.parseDouble(patientData.lat),
                        Double.parseDouble(patientData.lng));

                Location homeL = new Location("homeL");
                homeL.setLatitude(homeLatLng.latitude);
                homeL.setLongitude(homeLatLng.longitude);

                Location currL = new Location("currL");
                currL.setLatitude(pat_cur_latLng.latitude);
                currL.setLongitude(pat_cur_latLng.longitude);

                double distance = homeL.distanceTo(currL);
                distance /= 1609.34; // converting to Miles
                if (distance <= 0.015) {
                    binding.distanceAwayTxt.setText(patientData.first_name + " is at Home");
                } else {
                    binding.distanceAwayTxt.setText(String.format(patientData.first_name + " is %.2f miles away", distance));
                }
            }
        } catch (NumberFormatException e) {
            // do nothing

        }

        StringBuilder senior_address = new StringBuilder("");

        if (patientData.address_line1 != null) {
            senior_address.append(patientData.address_line1).append(", ");
        }

        if (patientData.city != null) {
            senior_address.append(patientData.city).append(", ");
        }

        if (patientData.state != null) {
            senior_address.append(patientData.state).append(", ");
        }

        if (patientData.country != null) {
            senior_address.append(patientData.country).append(".");
        }

        binding.homeAddress.setText(senior_address);
    }

    private void updatePatientAddress() {
        if (this.mHomeLatLng == null) return;

        try {
            // fetching address from the lag lng
            Geocoder geocoder = new Geocoder(this, Locale.getDefault());
            List<Address> addresses = geocoder.getFromLocation(mHomeLatLng.latitude, mHomeLatLng.longitude, 1);

            if (addresses != null && addresses.size() > 0 && addresses.get(0) != null) {
                Address address = addresses.get(0);

                progressDialog.setTitle("Please wait...");
                progressDialog.setMessage("while we update the patients address");
                progressDialog.setCancelable(false);
                progressDialog.show();

                Map<String, String> body = new HashMap<>();

                String addressLine;
                if (this.selectedStreet == null) {
                    addressLine = "";
                    if (address.getMaxAddressLineIndex() >= 0 && address.getAddressLine(0) != null) {
                        String[] addressLines = address.getAddressLine(0).split(",");
                        for (int i = 0; i < Math.min(1, addressLines.length); i++) {
                            addressLine = addressLine.concat(addressLines[i]);
                        }
                    }

                    if (addressLine.isEmpty()){
                        addressLine = (address.getThoroughfare() != null ? address.getThoroughfare() : address.getSubThoroughfare());
                    }
                } else {
                    addressLine = this.selectedStreet;
                }

                body.put("town", (address.getSubLocality() != null ? address.getSubLocality() : address.getLocality()));
                body.put("street", addressLine);
                body.put("state", address.getAdminArea());
                body.put("country", address.getCountryName());
                body.put("zip_code", address.getPostalCode());
                body.put("lat", this.mHomeLatLng.latitude + "");
                body.put("lng", this.mHomeLatLng.longitude + "");

                viewModel.updatePatientAddress(careGiverData.patientId, body,
                        "Bearer " + AppUtil.getCgToken(this),
                        this);
            } else {
                Toast.makeText(this, "Couldn't load address.", Toast.LENGTH_SHORT).show();
            }

        } catch (Exception e) {
            // do nothing as we couldn't load the location from the lat lng
            Toast.makeText(this, "Couldn't load address.", Toast.LENGTH_SHORT).show();
        }
    }

    private void saveGeoFence() {
        if (careGiverData == null) {
            Toast.makeText(this, "Couldn't add Fence.", Toast.LENGTH_SHORT).show();
            return;
        }

        Float radius = getRadius();

        if (radius == null) {
            Toast.makeText(this, "Invalid radius", Toast.LENGTH_SHORT).show();
            return;
        }

        if (geofence_bs_binding.message.getText().toString().trim().isEmpty()){
            // message is important
            geofence_bs_binding.message.setError("Required");
            return;
        }else {
            geofence_bs_binding.message.setError(null);
        }

        // convert to meters
        if (geofence_bs_binding.unitSpinner.getSelectedIndex() == 1) {
            // it is miles
            radius = radius * 1609.34f; // to meters
            if (radius < 160.934 || radius > 8046.72) {
                new AlertDialog.Builder(this)
                        .setMessage("Please select radius between\n0.1 mile - 5 mile")
                        .setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
                            dialogInterface.dismiss();
                        }).show();
                return;
            }
        } else {
            // it is kms
            radius = radius * 1000; // to meters
            if (radius < 100 || radius > 8000) {
                new AlertDialog.Builder(this)
                        .setMessage("Please select radius between\n0.1 km - 8 km")
                        .setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> {
                            dialogInterface.dismiss();
                        }).show();
                return;
            }
        }

        geoFenceDetails.message = geofence_bs_binding.message.getText().toString();
        geoFenceDetails.radius = "" + radius;
        geoFenceDetails.type = geofence_bs_binding.unitSpinner.getSelectedIndex() == 0 ? KMS : MILES;
        geoFenceDetails.patient_xid = "" + careGiverData.patientId;
        geoFenceDetails.caregiver_xid = "" + careGiverData.caregiver_xid;

        progressDialog.setTitle("Please wait...");
        progressDialog.setMessage("while we set Geofence for you.");
        progressDialog.setCancelable(false);
        progressDialog.show();

        viewModel.saveGeoFenceDetails(geoFenceDetails,
                "Bearer " + AppUtil.getCgToken(this),
                this);

    }

    private void addRadius(float radius) {
        if (mMap == null) return;

        CircleOptions circleOptions = new CircleOptions();
        circleOptions.center(mHomeLatLng);
        circleOptions.radius(radius);
        circleOptions.strokeWidth(0);
        circleOptions.fillColor(Color.argb(150, 167, 205, 242));

        if (radius_circle != null) radius_circle.remove();

        radius_circle = mMap.addCircle(circleOptions);
        bottomSheetDialog.dismiss();
    }

    private Float getRadius() {
        Float radius = null;

        try {
            radius = Float.valueOf(geofence_bs_binding.radius.getText().toString());
        } catch (Exception e) {
            // do nothing
            Log.e(TAG, "getRadius: ", e);
        }

        return radius;
    }

    @Override
    public void onMapReady(@NonNull GoogleMap googleMap) {
        this.mMap = googleMap;

        loadPatientsLocation();

        updateCurrentLocationPatientMarker();

        mMap.setOnMapClickListener(latLng1 -> {
            if (binding.search.getVisibility() != View.VISIBLE) {
                // search bar is not visible
                // user is not intending to change the home location
                return;
            }

            this.mHomeLatLng = latLng1;
            isTrackingSenior = false;
            this.selectedStreet = null;

            // checking is user selected same address
            try {
                if (patientData == null) throw new Exception();

                double lat = Double.parseDouble(patientData.lat);
                double lng = Double.parseDouble(patientData.lng);

                if (mHomeLatLng.latitude != lat || mHomeLatLng.longitude != lng){
                    binding.updateBtnsView.setVisibility(View.VISIBLE);
                    binding.homeLocationBtn.setVisibility(View.GONE);
                    binding.cgLocationBtn.setVisibility(View.GONE);
                }else {
                    binding.updateBtnsView.setVisibility(View.GONE);
                    binding.homeLocationBtn.setVisibility(View.VISIBLE);
                    binding.cgLocationBtn.setVisibility(View.VISIBLE);
                }
            } catch (Exception e) {
                // near marine drive
                binding.updateBtnsView.setVisibility(View.VISIBLE);
                binding.homeLocationBtn.setVisibility(View.GONE);
                binding.cgLocationBtn.setVisibility(View.GONE);
            }

            updateHomeMarker(this.mHomeLatLng);
            addRadius();
        });
    }

    private void updateCurrentLocationPatientMarker() {
        if (pat_cur_latLng != null) {
            String name;
            if (patientData != null) name = patientData.first_name;
            else name = "Senior's location";

            MarkerOptions options = new MarkerOptions()
                    .position(pat_cur_latLng)
                    .icon(BitmapDescriptorFactory.fromResource(R.drawable.img_pat_curr_location))
                    .title(name)
                    .draggable(false);

            if (curr_loc_marker != null) curr_loc_marker.remove();
            curr_loc_marker = mMap.addMarker(options);

            if (isTrackingSenior) {
                mMap.animateCamera(CameraUpdateFactory.newLatLng(pat_cur_latLng));
            }
        }
    }

    private void loadPatientsLocation() {
        LatLng home_lat_lng;

        // loading patient's location
        try {
            if (patientData == null) throw new Exception();

            double lat = Double.parseDouble(patientData.lat);
            double lng = Double.parseDouble(patientData.lng);

            home_lat_lng = new LatLng(lat, lng);
            updateHomeMarker(home_lat_lng);
            addRadius();

            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home_lat_lng, 14));
        } catch (Exception e) {
            // near marine drive
            Toast.makeText(this, "Couldn't load home location", Toast.LENGTH_SHORT).show();
        }
    }

    private void addRadius() {
        try {
            if (geoFenceDetails.radius != null) {
                float radius = Float.parseFloat(geoFenceDetails.radius);
                addRadius(radius);
            }
        } catch (Exception e) {
            Log.e(TAG, "onMapReady: ", e);
            Toast.makeText(this, "Couldn't load geofence.", Toast.LENGTH_SHORT).show();
        }
    }

    private void updateHomeMarker(@NonNull LatLng home_latLng) {
        if (mMap == null || patientData == null) return;

        this.mHomeLatLng = home_latLng;

        MarkerOptions markerOptions = new MarkerOptions()
                .position(home_latLng)
                .draggable(false)
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.img_home_marker))
                .title("Home location");

        if (home_loc_marker != null) home_loc_marker.remove();

        home_loc_marker = mMap.addMarker(markerOptions);
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(home_latLng, 14));
    }

    private void registerMapSearchResultLauncher() {

        // initializing places
        // Initialize the SDK
        Places.initialize(this, getString(R.string.GOOGLE_MAPS_API_KEY));

        startAutocompleteMapSearch = registerForActivityResult(
                new ActivityResultContracts.StartActivityForResult(),
                result -> {
                    if (result.getResultCode() == Activity.RESULT_OK) {
                        Intent intent = result.getData();
                        if (intent != null) {
                            Place place = Autocomplete.getPlaceFromIntent(intent);

                            if (place.getLatLng() == null) return;

                            this.mHomeLatLng = place.getLatLng();
                            this.selectedStreet = place.getName();

                            // checking is user selected same address
                            try {
                                if (patientData == null) throw new Exception();

                                double lat = Double.parseDouble(patientData.lat);
                                double lng = Double.parseDouble(patientData.lng);

                                if (mHomeLatLng.latitude != lat || mHomeLatLng.longitude != lng){
                                    binding.updateBtnsView.setVisibility(View.VISIBLE);
                                    binding.homeLocationBtn.setVisibility(View.GONE);
                                    binding.cgLocationBtn.setVisibility(View.GONE);
                                }else{
                                    binding.updateBtnsView.setVisibility(View.GONE);
                                    binding.homeLocationBtn.setVisibility(View.VISIBLE);
                                    binding.cgLocationBtn.setVisibility(View.VISIBLE);
                                }
                            } catch (Exception e) {
                                // near marine drive
                                binding.updateBtnsView.setVisibility(View.VISIBLE);
                                binding.homeLocationBtn.setVisibility(View.GONE);
                                binding.cgLocationBtn.setVisibility(View.GONE);
                            }

                            updateHomeMarker(this.mHomeLatLng);
                            addRadius();
                        }
                    }
                });
    }

    @Override
    public void onGeofenceDetailsSaved(GeoFenceDetails geoFenceDetails) {
        progressDialog.dismiss();
        this.geoFenceDetails = geoFenceDetails;

        binding.updateBtnsView.setVisibility(View.GONE);
        binding.homeLocationBtn.setVisibility(View.VISIBLE);
        binding.cgLocationBtn.setVisibility(View.VISIBLE);

        binding.search.setVisibility(View.GONE);
        binding.changeBtn.setText(getString(R.string.change));

        Toast.makeText(this, "Geofence updated successfully", Toast.LENGTH_SHORT).show();

        bottomSheetDialog.dismiss();

        updateHomeMarker(mHomeLatLng);
        addRadius();
    }

    @Override
    public void onGeofenceDetailsSaveFailed(Throwable throwable, String message) {
        progressDialog.dismiss();
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onPatientAddressUpdated(@NonNull PatientData patientData) {
        binding.updateBtnsView.setVisibility(View.GONE);
        binding.homeLocationBtn.setVisibility(View.VISIBLE);
        binding.cgLocationBtn.setVisibility(View.VISIBLE);

        binding.search.setVisibility(View.GONE);
        binding.changeBtn.setText(getString(R.string.change));

        this.careGiverData.patientDetails = patientData;
        this.patientData = patientData;
        CaregiverDataCache.setCareGiverData(this.careGiverData);
        progressDialog.dismiss();
        updatePatientCurrentLocationDetails();
        Toast.makeText(this, "Senior geofence updated successfully", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onPatientAddressUpdateFailed(Throwable throwable, String message) {
        progressDialog.dismiss();
        Toast.makeText(this, "Couldn't update patient's location.", Toast.LENGTH_SHORT).show();
    }
}