package com.example.pap_findu;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.util.Log;

import androidx.annotation.NonNull;

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.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;

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

public class GeofenceManager {

    private static final String TAG = "GeofenceManager";
    private final Context context;
    private final GeofencingClient geofencingClient;
    private final FirebaseFirestore db;
    private PendingIntent geofencePendingIntent;

    public GeofenceManager(Context context) {
        this.context = context;
        this.geofencingClient = LocationServices.getGeofencingClient(context);
        this.db = FirebaseFirestore.getInstance();
    }

    public void setupGeofences() {
        // Isolamento de dados: só escutar zonas deste filho
        String childCode = context.getSharedPreferences("FindU_Prefs", Context.MODE_PRIVATE)
                .getString("child_access_code", null);
        if (childCode == null) {
            Log.w(TAG, "childCode nulo, geofences não serão configuradas.");
            return;
        }

        // Escuta a coleção "SafeZones" filtrada por childCode em tempo real
        db.collection("SafeZones")
                .whereEqualTo("childCode", childCode)
                .addSnapshotListener((value, error) -> {
            if (error != null) {
                Log.e(TAG, "Listen failed: " + error.getMessage());
                return;
            }

            if (value != null) {
                List<Geofence> geofenceList = new ArrayList<>();
                for (DocumentSnapshot doc : value.getDocuments()) {
                    String id = doc.getId();
                    Double lat = doc.getDouble("latitude");
                    Double lng = doc.getDouble("longitude");
                    Double radius = doc.getDouble("radius");
                    
                    if (radius == null) radius = 200.0;

                    if (lat != null && lng != null) {
                        Geofence geofence = new Geofence.Builder()
                                .setRequestId(id)
                                .setCircularRegion(lat, lng, radius.floatValue())
                                .setExpirationDuration(Geofence.NEVER_EXPIRE)
                                // Detetar entrada E saída da zona segura.
                                .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
                                .build();
                        
                        geofenceList.add(geofence);
                    }
                }

                if (!geofenceList.isEmpty()) {
                    registerGeofences(geofenceList);
                } else {
                    removeGeofences();
                }
            }
        });
    }

    private void registerGeofences(List<Geofence> geofenceList) {
        GeofencingRequest geofencingRequest = new GeofencingRequest.Builder()
                .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER | GeofencingRequest.INITIAL_TRIGGER_EXIT)
                .addGeofences(geofenceList)
                .build();

        try {
            geofencingClient.addGeofences(geofencingRequest, getGeofencePendingIntent())
                    .addOnSuccessListener(aVoid -> Log.d(TAG, "Geofences adicionadas com sucesso!"))
                    .addOnFailureListener(e -> Log.e(TAG, "Erro ao adicionar geofences: " + e.getMessage()));
        } catch (SecurityException securityException) {
            Log.e(TAG, "Falta permissão para Geofences: " + securityException.getMessage());
        }
    }

    private void removeGeofences() {
        if (geofencePendingIntent != null) {
            geofencingClient.removeGeofences(geofencePendingIntent)
                    .addOnSuccessListener(aVoid -> Log.d(TAG, "Geofences removidas com sucesso"))
                    .addOnFailureListener(e -> Log.e(TAG, "Erro ao remover geofences: " + e.getMessage()));
        }
    }

    private PendingIntent getGeofencePendingIntent() {
        if (geofencePendingIntent != null) {
            return geofencePendingIntent;
        }
        Intent intent = new Intent(context, GeofenceBroadcastReceiver.class);
        
        int flags = PendingIntent.FLAG_UPDATE_CURRENT;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            flags |= PendingIntent.FLAG_MUTABLE;
        }

        geofencePendingIntent = PendingIntent.getBroadcast(context, 0, intent, flags);
        return geofencePendingIntent;
    }
}
