package com.app.simplitend.apputils;

import static com.app.simplitend.locationupdates.LocationService.LOCATION_INTERVAL_BASE_TIME;
import static com.app.simplitend.locationupdates.LocationService.LOCATION_UPDATE_MIN_INTERVAL;
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_ID;
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG;

import android.Manifest;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresPermission;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.app.simplitend.locationupdates.LocationService;
import com.app.simplitend.patientgeofencing.GeoFenceHelper;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingClient;
import com.google.android.gms.location.GeofencingRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.model.LatLng;

public class BootCompleteReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            // starting over the Location updates service again
            Intent locationUpdateIntent = new Intent(context, LocationService.class);
            locationUpdateIntent.setAction(LocationService.ACTION_START_LOCATION_UPDATES);
            locationUpdateIntent.putExtra(LOCATION_UPDATE_MIN_INTERVAL, LOCATION_INTERVAL_BASE_TIME);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(locationUpdateIntent);
            } else {
                context.startService(locationUpdateIntent);
            }

            // setting up geofence if available
            String radius_str = AppUtil.getPatientGeofenceRadius(context);
            if (radius_str != null) {
                float radius_f;
                try {
                    radius_f = Float.parseFloat(radius_str);
                } catch (NumberFormatException e) {
                    radius_f = 0;
                }

                if (radius_f != 0) {
                    String[] latLngStr = AppUtil.getPatientLatLng(context);
                    if (latLngStr[0] != null && latLngStr[1] != null) {
                        LatLng latLng;
                        try {
                            latLng = new LatLng(Double.parseDouble(latLngStr[0]),
                                    Double.parseDouble(latLngStr[1]));
                        } catch (Exception e) {
                            latLng = null;
                        }

                        if (latLng != null) {
                            if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                                return;
                            }
                            addGeoFence(latLng, radius_f, context);
                        }
                    }
                }
            }
        }
    }

    @RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION)
    private void addGeoFence(@NonNull LatLng latLng, float GEOFENCING_RADIUS , Context context) {

        GeoFenceHelper geoFenceHelper = new GeoFenceHelper(context);
        GeofencingClient geofencingClient = LocationServices.getGeofencingClient(context);

        // checking for background location updates for API level 29 and above
        if (Build.VERSION.SDK_INT >= 29) {
            if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                Log.d(GEOFENCE_TAG, "setGeofence: NO BACKGROUND PERMISSION" );
                return;
            }
        }

        Geofence geofence = geoFenceHelper.getGeoFence(GEOFENCE_ID, latLng, GEOFENCING_RADIUS,
                Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT);
        GeofencingRequest geofencingRequest = geoFenceHelper.getGeoFencingRequest(geofence);
        PendingIntent pendingIntent = geoFenceHelper.getPendingIntent();

        geofencingClient.addGeofences(geofencingRequest, pendingIntent)
                .addOnSuccessListener(aVoid -> {
                    Log.d(GEOFENCE_TAG, "Geofence added successfully. " + latLng + " Radius: " + GEOFENCING_RADIUS + " meters");
                })
                .addOnFailureListener(e -> {
                    Log.d(GEOFENCE_TAG, "onFailure: Geofence couldn't be added: " + e.getLocalizedMessage()  + " " + latLng + " Radius: " + GEOFENCING_RADIUS);
                });

    }
}
