package com.noovudev.geofence.capacitorgeofenceboxtracker;

import android.Manifest;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.location.Location;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.util.Log;

import com.getcapacitor.JSObject;
import com.getcapacitor.NativePlugin;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
import com.getcapacitor.PluginRequestCodes;
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.LocationListener;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnSuccessListener;

@NativePlugin(permissions = { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION }, permissionRequestCode = PluginRequestCodes.GEOLOCATION_REQUEST_PERMISSIONS)

public class GeofenceTracker extends Plugin implements LocationListener {

    private static final String TAG = GeofenceTracker.class.getSimpleName();
    private boolean notifyOnEntry = false;
    private boolean notifyOnExit = false;
    private GeofencingClient geofencingClient;
    private PendingIntent geoFencePendingIntent;
    MyReceiver myReceiver;

    @PluginMethod()
    public void setup(PluginCall call) {
        notifyOnEntry = call.getBoolean("notifyOnEntry");
        notifyOnExit = call.getBoolean("notifyOnExit");

        if (!hasRequiredPermissions()) {
            saveCall(call);
            pluginRequestAllPermissions();
        } else {
//            startWatch(call);
        }

        call.success();
    }

    private PendingIntent createGeofencePendingIntent() {
        Log.d(TAG, "createGeofencePendingIntent");
        if ( geoFencePendingIntent != null )
            return geoFencePendingIntent;

        Intent intent = new Intent(this.getContext(), GeofenceIntentService.class);
        return PendingIntent.getService(
                this.getContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT );
    }

    public void notifyTracker(String identifer, int geofenceTransition) {
        JSObject ret = new JSObject();

        ret.put("identifer", identifer);

        if(geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER) {
            ret.put("enter", true);
        } else if(geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {
            ret.put("enter", false);
        }

        notifyListeners("onTransitionReceived", ret);
    }

    @PluginMethod()
    public void addRegion(PluginCall call) {
        double latitude = Double.parseDouble(call.getData().getString("latitude"));
        double longitude = Double.parseDouble(call.getData().getString("longitude"));
        float radius = Float.parseFloat(call.getData().getString("radius"));
        String identifier = call.getData().getString("identifier");

        myReceiver = new MyReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("location");

        LocalBroadcastManager.getInstance(this.getContext()).registerReceiver(myReceiver, intentFilter);

        geofencingClient = LocationServices.getGeofencingClient(this.getContext());

        Geofence geofence = new Geofence.Builder()
                .setRequestId(identifier)
                .setCircularRegion(latitude, longitude, radius)
                .setExpirationDuration(Geofence.NEVER_EXPIRE)
                .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
                        Geofence.GEOFENCE_TRANSITION_EXIT)
                .build();

        GeofencingRequest request = new GeofencingRequest.Builder()
                .setInitialTrigger(Geofence.GEOFENCE_TRANSITION_ENTER |
                        Geofence.GEOFENCE_TRANSITION_EXIT)
                .addGeofence(geofence)
                .build();

        geofencingClient.addGeofences(request, createGeofencePendingIntent()).addOnSuccessListener((Activity) this.getContext(), new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                Log.d("onSuccess", aVoid + "");
            }
        });

        call.success();
    }

    @PluginMethod()
    public void stopMonitoring(PluginCall call) {
        geofencingClient.removeGeofences(createGeofencePendingIntent());

        call.success();
    }

    @PluginMethod()
    public void monitoredRegions(PluginCall call) {
        call.success();
    }

    @PluginMethod()
    public void registerForPushNotifications(PluginCall call) {
        call.success();
    }

    @Override
    protected void handleRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.handleRequestPermissionsResult(requestCode, permissions, grantResults);

        PluginCall savedCall = getSavedCall();
        if (savedCall == null) {
            return;
        }

        for (int result : grantResults) {
            if (result == PackageManager.PERMISSION_DENIED) {
                savedCall.error("User denied location permission");
                return;
            }
        }
    }

    @Override
    public void onLocationChanged(Location location) {

    }

    class MyReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String geofenceTransitionDetails = intent.getStringExtra("broadcastMessage");
            String[] details = geofenceTransitionDetails.split("//");
            notifyTracker(details[0], Integer.parseInt(details[1]));
            Log.d("BROADCAST MESSAGE", geofenceTransitionDetails);
        }
    }
}