package com.dittomart.meatsbhavan.web.webChromeClient;

import static com.dittomart.meatsbhavan.util.Constant.BASE_URL;
import static com.dittomart.meatsbhavan.util.Constant.REQUEST_FINE_LOCATION;
import static com.dittomart.meatsbhavan.util.Constant.REQUEST_FOR_GPS;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.IntentSender;
import android.location.LocationManager;
import android.os.Build;
import android.util.Log;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.os.Handler;
import android.os.Looper;

import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import com.dittomart.meatsbhavan.R;
import com.dittomart.meatsbhavan.ui.MainActivity;
import com.dittomart.meatsbhavan.util.PermissionUtil;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.tasks.Task;
import com.google.android.material.snackbar.Snackbar;


public class MyWebChromeClient extends WebChromeClient {
    private static final String TAG = MyWebChromeClient.class.getSimpleName();
    private LocationManager locationManager;
    private Activity context;
    private WebView webview;
    private SwipeRefreshLayout swipe;

    public MyWebChromeClient(LocationManager locationManager, Activity context, WebView webview, SwipeRefreshLayout swipe) {
        this.locationManager = locationManager;
        this.context = context;
        this.webview = webview;
        this.swipe = swipe;
    }

    @Override
    public void onProgressChanged(WebView view, int newProgress) {
        super.onProgressChanged(view, newProgress);
        Log.d(TAG, "onProgressChanged: " + view.getUrl());
        swipe.setEnabled(!BASE_URL.concat("my-location").equals(view.getUrl()) && !view.getUrl().contains("running-order"));
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
        super.onGeolocationPermissionsShowPrompt(origin, callback);
        Log.d(TAG, "onGeolocationPermissionsShowPrompt called for origin: " + origin);
        
        // Store callback and origin for later use
        MainActivity.mGeolocationOrigin = origin;
        MainActivity.mGeolocationCallback = callback;
        
        // Device-specific GPS handling
        handleDeviceSpecificGPS(origin, callback);
    }
    
    /**
     * Handle GPS permissions with device-specific workarounds
     */
    private void handleDeviceSpecificGPS(String origin, GeolocationPermissions.Callback callback) {
        String manufacturer = Build.MANUFACTURER.toLowerCase();
        Log.d(TAG, "Device manufacturer: " + manufacturer);
        
        // Check if we have location permission first
        String perm = Manifest.permission.ACCESS_FINE_LOCATION;
        PermissionUtil.checkPermission(context, perm, new PermissionUtil.PermissionAskListener() {
            @Override
            public void onPermissionAsk() {
                Log.d(TAG, "onPermissionAsk: Requesting location permission");
                MainActivity.mGeolocationOrigin = origin;
                MainActivity.mGeolocationCallback = callback;
                ActivityCompat.requestPermissions(context, new String[]{perm}, REQUEST_FINE_LOCATION);
            }

            @Override
            public void onPermissionPreviouslyDenied() {
                Log.d(TAG, "onPermissionPreviouslyDenied: Re-requesting location permission");
                MainActivity.mGeolocationOrigin = origin;
                MainActivity.mGeolocationCallback = callback;
                ActivityCompat.requestPermissions(context, new String[]{perm}, REQUEST_FINE_LOCATION);
            }

            @Override
            public void onPermissionDisabled() {
                Log.d(TAG, "onPermissionDisabled: Location permission disabled");
                MainActivity.mGeolocationOrigin = origin;
                MainActivity.mGeolocationCallback = callback;
                ActivityCompat.requestPermissions(context, new String[]{perm}, REQUEST_FINE_LOCATION);
                Snackbar.make(webview, "GPS is Disabled. Please enable location permission in settings.", Snackbar.LENGTH_LONG).show();
            }

            @Override
            public void onPermissionGranted() {
                Log.d(TAG, "onPermissionGranted: Location permission granted");
                locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

                // Device-specific location handling
                if (isLocationEnabled()) {
                    Log.d(TAG, "Location services already enabled, granting permission");
                    // For some devices, we need to delay the callback
                    if (manufacturer.contains("xiaomi") || manufacturer.contains("redmi") || 
                        manufacturer.contains("vivo") || manufacturer.contains("iqoo")) {
                        // Delay for MIUI and Vivo devices
                        new Handler(Looper.getMainLooper()).postDelayed(() -> {
                            callback.invoke(origin, true, false);
                        }, 500);
                    } else {
                        callback.invoke(origin, true, false);
                    }
                } else {
                    Log.d(TAG, "Location services not enabled, requesting to enable");
                    locationEnabled();
                }
            }
        });
    }

    // Check if location services are enabled (GPS or Network)
    private boolean isLocationEnabled() {
        if (locationManager == null) {
            locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        }
        return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || 
               locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    }

    //Gps Request with enhanced device compatibility
    public void locationEnabled() {
        try {
            LocationRequest locationRequest = LocationRequest.create()
                    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                    .setInterval(3000)
                    .setFastestInterval(1000);

            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                    .addLocationRequest(locationRequest);
            builder.setAlwaysShow(true);

            Task<LocationSettingsResponse> responseTask = LocationServices.getSettingsClient(context)
                    .checkLocationSettings(builder.build());

            // Add timeout mechanism
            Handler handler = new Handler(Looper.getMainLooper());
            Runnable timeoutRunnable = () -> {
                Log.w(TAG, "Location settings check timed out");
                if (MainActivity.mGeolocationCallback != null && MainActivity.mGeolocationOrigin != null) {
                    MainActivity.mGeolocationCallback.invoke(MainActivity.mGeolocationOrigin, false, false);
                }
            };
            handler.postDelayed(timeoutRunnable, 15000); // Increased to 15 seconds for slower devices

            responseTask.addOnCompleteListener(task -> {
                handler.removeCallbacks(timeoutRunnable); // Cancel timeout
                try {
                    LocationSettingsResponse response = task.getResult(ApiException.class);
                    Log.d(TAG, "Location settings check successful - GPS is On");
                    
                    // Device-specific delay for callback
                    String manufacturer = Build.MANUFACTURER.toLowerCase();
                    if (manufacturer.contains("xiaomi") || manufacturer.contains("redmi") || 
                        manufacturer.contains("vivo") || manufacturer.contains("iqoo") ||
                        manufacturer.contains("oppo") || manufacturer.contains("oneplus")) {
                        // Delay for custom Android skins
                        new Handler(Looper.getMainLooper()).postDelayed(() -> {
                            if (MainActivity.mGeolocationCallback != null && MainActivity.mGeolocationOrigin != null) {
                                MainActivity.mGeolocationCallback.invoke(MainActivity.mGeolocationOrigin, true, false);
                            }
                        }, 1000);
                    } else {
                        // Standard callback
                        if (MainActivity.mGeolocationCallback != null && MainActivity.mGeolocationOrigin != null) {
                            MainActivity.mGeolocationCallback.invoke(MainActivity.mGeolocationOrigin, true, false);
                        }
                    }
                } catch (ApiException e) {
                    Log.e(TAG, "Location settings error: " + e.getStatusCode());
                    switch (e.getStatusCode()) {
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            try {
                                ResolvableApiException exception = (ResolvableApiException) e;
                                exception.startResolutionForResult(context, REQUEST_FOR_GPS);
                            } catch (IntentSender.SendIntentException sendIntentException) {
                                sendIntentException.printStackTrace();
                                Log.e(TAG, "Could not start resolution for location settings");
                                // Fallback: try to grant permission anyway for some devices
                                if (MainActivity.mGeolocationCallback != null && MainActivity.mGeolocationOrigin != null) {
                                    MainActivity.mGeolocationCallback.invoke(MainActivity.mGeolocationOrigin, true, false);
                                }
                            }
                            break;

                        case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                            Log.w(TAG, "Location settings cannot be changed");
                            // For some devices, grant permission anyway
                            if (MainActivity.mGeolocationCallback != null && MainActivity.mGeolocationOrigin != null) {
                                MainActivity.mGeolocationCallback.invoke(MainActivity.mGeolocationOrigin, true, false);
                            }
                            break;
                            
                        default:
                            Log.e(TAG, "Unknown location settings error: " + e.getStatusCode());
                            if (MainActivity.mGeolocationCallback != null && MainActivity.mGeolocationOrigin != null) {
                                MainActivity.mGeolocationCallback.invoke(MainActivity.mGeolocationOrigin, false, false);
                            }
                            break;
                    }
                }
            });
        } catch (Exception e) {
            Log.e(TAG, "Error in locationEnabled: " + e.getMessage());
            // Fallback: grant permission anyway
            if (MainActivity.mGeolocationCallback != null && MainActivity.mGeolocationOrigin != null) {
                MainActivity.mGeolocationCallback.invoke(MainActivity.mGeolocationOrigin, true, false);
            }
        }
    }

}
