package com.example.epl498_labs.ui.location;

import android.Manifest;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import android.util.Log;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;

import com.example.epl498_labs.R;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofenceStatusCodes;
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.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.CircleOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;

import java.util.ArrayList;
import java.util.List;

public class GeofenceFragment extends Fragment implements OnMapReadyCallback {

    private GoogleMap mMap;
    private GeofencingClient geofencingClient;
    private List<Geofence> geofenceList;
    private PendingIntent geofencePendingIntent;
    private final int GEOFENCE_RADIUS = 100; // Geofence radius in meters

    // Declare the ActivityResultLauncher for requesting permissions
    private ActivityResultLauncher<String[]> requestPermissionLauncher;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Initialize the ActivityResultLauncher to request location permissions
        requestPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), permissionsResult -> {
            if (permissionsResult.get(Manifest.permission.ACCESS_FINE_LOCATION) == Boolean.TRUE) {
                // Location permission granted, proceed with your code
            } else {
                Toast.makeText(requireContext(), "Location permission denied", Toast.LENGTH_SHORT).show();
            }
        });

        // Initialize GeofencingClient for managing geofences
        geofencingClient = LocationServices.getGeofencingClient(requireContext());

        // Initialize the list to store geofences
        geofenceList = new ArrayList<>();

        // Create a geofence for the University of Cyprus campus and add it to the list
        createGeofenceList();

        // Create a PendingIntent to handle geofence transitions
        createGeofencePendingIntent();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_geofence, container, false);

        // Initialize the MapView
        MapView mapView = rootView.findViewById(R.id.mapView);
        mapView.onCreate(savedInstanceState);
        mapView.onResume();
        mapView.getMapAsync(this);

        return rootView;
    }

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

        // Enable the "My Location" layer (blue dot) on the map
        mMap.setMyLocationEnabled(true);

        // Add a marker for the University of Cyprus campus (Replace with actual coordinates)
        LatLng universityLocation = new LatLng(35.1469, 33.4093);
        mMap.addMarker(new MarkerOptions().position(universityLocation).title("University of Cyprus"));
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(universityLocation, 14));

        // Check location permission before drawing geofences and adding them
        checkLocationPermission();
        drawGeofences(); // Draw geofences on the map

        // Call addGeofences to start monitoring the geofences
        addGeofences();
    }

    // Draw geofences as circles on the map
    private void drawGeofences() {
        for (Geofence geofence : geofenceList) {
            LatLng geofenceCenter = new LatLng(
                    geofence.getRequestId().equals("universityGeofence") ? 35.1469 : 0,
                    geofence.getRequestId().equals("universityGeofence") ? 33.4093 : 0
            );

            CircleOptions circleOptions = new CircleOptions()
                    .center(geofenceCenter)
                    .radius(GEOFENCE_RADIUS)
                    .strokeColor(Color.RED)
                    .fillColor(Color.argb(70, 150, 50, 50)); // Customize the circle appearance as needed

            mMap.addCircle(circleOptions);
        }
    }

    // Check for location permission at runtime using requestPermissionLauncher
    private void checkLocationPermission() {
        String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION};
        requestPermissionLauncher.launch(permissions);
    }

    // Create a geofence for the University of Cyprus campus and add it to the list
    private void createGeofenceList() {
        // Use the actual coordinates of the University of Cyprus campus
        LatLng universityLocation = new LatLng(35.1469, 33.4093);
        Geofence geofence = new Geofence.Builder()
                .setRequestId("universityGeofence")
                .setCircularRegion(
                        universityLocation.latitude,
                        universityLocation.longitude,
                        GEOFENCE_RADIUS
                )
                .setExpirationDuration(Geofence.NEVER_EXPIRE)
                .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
                        Geofence.GEOFENCE_TRANSITION_EXIT)
                .build();
        geofenceList.add(geofence);
    }

    // Create a PendingIntent for geofence transitions
    private void createGeofencePendingIntent() {
        Intent intent = new Intent(requireContext(), GeofenceBroadcastReceiver.class);
        geofencePendingIntent = PendingIntent.getBroadcast(requireContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
    }

    // Add geofences to start monitoring
    private void addGeofences() {
        if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            GeofencingRequest.Builder builder = new GeofencingRequest.Builder();

            // Specify the initial triggers for geofence events
            builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);

            // Add the geofences to the builder
            builder.addGeofences(geofenceList);

            // Build the GeofencingRequest
            GeofencingRequest geofencingRequest = builder.build();

            // Add the geofences with the request
            geofencingClient.addGeofences(geofencingRequest, geofencePendingIntent)
                    .addOnCompleteListener(requireActivity(), new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> task) {
                            if (task.isSuccessful()) {
                                // Geofences added successfully
                                Toast.makeText(requireContext(), "Geofences added", Toast.LENGTH_SHORT).show();
                            } else {
                                // Geofences failed to add
                                String msg = String.valueOf(task.getException());
                                Toast.makeText(requireContext(), "Error: " + msg, Toast.LENGTH_SHORT).show();
                                Log.e("Geofence", msg);
                            }
                        }
                    });
        }
    }
}
