package com.cpm.lorealbaautomation;

import static com.google.android.gms.location.Priority.PRIORITY_HIGH_ACCURACY;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationRequest;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;

import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.Priority;


public class LocationEngine {

    public interface LocationResultListener {
        void onLocationReady(Location location, float accuracy);
        void onFailure(String msg);
    }

    private final Context context;
    private final FusedLocationProviderClient fusedClient;

    private LocationCallback locationCallback;

    private Location bestLocation = null;
    private float bestAccuracy = Float.MAX_VALUE;

    private Handler handler = new Handler(Looper.getMainLooper());

    public LocationEngine(Context context) {
        this.context = context;
        fusedClient = LocationServices.getFusedLocationProviderClient(context);
    }

    public void start(LocationResultListener listener) {

        com.google.android.gms.location.LocationRequest request = new com.google.android.gms.location.LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY,  2000L)
                .setMinUpdateIntervalMillis(1000L)
                .setMaxUpdateDelayMillis(3000L)
                .setWaitForAccurateLocation(true) // Optional, improves first fix
                .build();

       /* LocationRequest request = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 2000L) // 👈 IMPORTANT
                .setMinUpdateIntervalMillis(1000L)
                .setMaxUpdateDelayMillis(3000L)
                .setWaitForAccurateLocation(true)
                .build();*/

        locationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(@NonNull LocationResult result) {

                for (Location location : result.getLocations()) {

                    if (location == null) continue;

                    float accuracy = location.getAccuracy();

                    // 🔥 Track best location always
                    if (accuracy < bestAccuracy) {
                        bestAccuracy = accuracy;
                        bestLocation = location;
                    }

                    Log.d("LocationEngine",
                            "Lat: " + location.getLatitude()
                                    + " Lng: " + location.getLongitude()
                                    + " Acc: " + accuracy);

                    // ✅ Accept good or stable location
                    if (accuracy <= 80) {
                        stop();
                        listener.onLocationReady(location, accuracy);
                        return;
                    }
                }
            }
        };

        if (ActivityCompat.checkSelfPermission(context,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            listener.onFailure("Permission not granted");
            return;
        }

        fusedClient.requestLocationUpdates(request, locationCallback, Looper.getMainLooper());

        // ⏱ Timeout fallback (VERY IMPORTANT)
        handler.postDelayed(() -> {

            if (bestLocation != null) {
                Log.d("LocationEngine", "Using fallback location");

                listener.onLocationReady(bestLocation, bestAccuracy);
            } else {
                listener.onFailure("Unable to fetch location");
            }

            stop();

        }, 8000);
    }

    public void stop() {
        if (locationCallback != null) {
            fusedClient.removeLocationUpdates(locationCallback);
        }
        handler.removeCallbacksAndMessages(null);
    }
}