package com.lyokone.location;

import android.os.Build;
import android.util.Log;
import androidx.annotation.Nullable;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

final class MethodCallHandlerImpl implements MethodCallHandler {
    private static final String TAG = "MethodCallHandlerImpl";

    private FlutterLocation location;
    private FlutterLocationService locationService;

    @Nullable
    private MethodChannel channel;

    private static final String METHOD_CHANNEL_NAME = "lyokone/location";

    void setLocation(FlutterLocation location) {
        this.location = location;
    }

    void setLocationService(FlutterLocationService locationService) {
        this.locationService = locationService;
    }

    @Override
    public void onMethodCall(MethodCall call, Result result) {
        switch (call.method) {
            case "changeSettings":
                onChangeSettings(call, result);
                break;
            case "getLocation":
                onGetLocation(result);
                break;
            case "hasPermission":
                onHasPermission(result);
                break;
            case "requestPermission":
                onRequestPermission(result);
                break;
            case "serviceEnabled":
                onServiceEnabled(result);
                break;
            case "requestService":
                location.requestService(result);
                break;
            case "isBackgroundModeEnabled":
                isBackgroundModeEnabled(result);
                break;
            case "enableBackgroundMode":
                enableBackgroundMode(call, result);
                break;
            default:
                result.notImplemented();
                break;
        }
    }

    /**
     * Registers this instance as a method call handler on the given
     * {@code messenger}.
     */
    void startListening(BinaryMessenger messenger) {
        if (channel != null) {
            Log.wtf(TAG, "Setting a method call handler before the last was disposed.");
            stopListening();
        }

        channel = new MethodChannel(messenger, METHOD_CHANNEL_NAME);
        channel.setMethodCallHandler(this);
    }

    /**
     * Clears this instance from listening to method calls.
     */
    void stopListening() {
        if (channel == null) {
            Log.d(TAG, "Tried to stop listening when no MethodChannel had been initialized.");
            return;
        }

        channel.setMethodCallHandler(null);
        channel = null;
    }

    private void onChangeSettings(MethodCall call, Result result) {
        try {
            final Integer locationAccuracy = location.mapFlutterAccuracy.get((Integer) call.argument("accuracy"));
            final Long updateIntervalMilliseconds = new Long((int) call.argument("interval"));
            final Long fastestUpdateIntervalMilliseconds = updateIntervalMilliseconds / 2;
            final Float distanceFilter = new Float((double) call.argument("distanceFilter"));

            location.changeSettings(locationAccuracy, updateIntervalMilliseconds, fastestUpdateIntervalMilliseconds,
                    distanceFilter);

            result.success(1);
        } catch (Exception e) {
            result.error("CHANGE_SETTINGS_ERROR",
                    "An unexcepted error happened during location settings change:" + e.getMessage(), null);
        }
    }

    private void onGetLocation(Result result) {
        location.getLocationResult = result;
        if (!location.checkPermissions()) {
            location.requestPermissions();
        } else {
            location.startRequestingLocation();
        }
    }

    private void onHasPermission(Result result) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            result.success(1);
            return;
        }

        if (location.checkPermissions()) {
            result.success(1);
        } else {
            result.success(0);
        }
    }

    private void onServiceEnabled(Result result) {
        try {
            result.success(location.checkServiceEnabled() ? 1 : 0);
        } catch (Exception e) {
            result.error("SERVICE_STATUS_ERROR", "Location service status couldn't be determined", null);
        }
    }

    private void onRequestPermission(Result result) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            result.success(1);
            return;
        }

        location.result = result;
        location.requestPermissions();
    }

    private void isBackgroundModeEnabled(Result result) {
        if (locationService != null) {
            result.success(this.locationService.isInForegroundMode() ? 1 : 0);
        } else {
            result.success(0);
        }
    }

    private void enableBackgroundMode(MethodCall call, Result result) {
        final Boolean enable = call.argument("enable");
        if (locationService != null && enable != null) {
            if (locationService.checkBackgroundPermissions()) {
                if (enable) {
                    locationService.enableBackgroundMode();

                    result.success(1);
                } else {
                    locationService.disableBackgroundMode();

                    result.success(0);
                }
            } else {
                if (enable) {
                    locationService.setResult(result);
                    locationService.requestBackgroundPermissions();
                } else {
                    locationService.disableBackgroundMode();

                    result.success(0);
                }
            }
        } else {
            result.success(0);
        }
    }
}

@@ -74,16 +74,17 @@
 il.Log;%0A
+%0A
 import a
@@ -112,16 +112,40 @@
 llable;%0A
+%0Aimport java.util.Map;%0A%0A
 import i
@@ -1899,32 +1899,160 @@
          break;%0A
+            case %22changeNotificationOptions%22:%0A                onChangeNotificationOptions(call, result);%0A                break;%0A
             defa
@@ -6066,11 +6066,1259 @@
  %7D%0A    %7D
+%0A%0A    private void onChangeNotificationOptions(MethodCall call, Result result) %7B%0A        try %7B%0A            String passedChannelName = call.argument(%22channelName%22);%0A            String channelName = passedChannelName != null%0A                    ? passedChannelName%0A                    : FlutterLocationServiceKt.kDefaultChannelName;%0A%0A            String passedTitle = call.argument(%22title%22);%0A            String title = passedTitle != null%0A                    ? passedTitle%0A                    : FlutterLocationServiceKt.kDefaultNotificationTitle;%0A%0A            String passedIconName = call.argument(%22iconName%22);%0A            String iconName = passedIconName != null%0A                    ? passedIconName%0A                    : FlutterLocationServiceKt.kDefaultNotificationIconName;%0A%0A            NotificationOptions options = new NotificationOptions(channelName, title, iconName);%0A            Map%3CString, Object%3E notificationMeta = this.locationService.changeNotificationOptions(options);%0A            result.success(notificationMeta);%0A        %7D catch (Exception e) %7B%0A            result.error(%22CHANGE_NOTIFICATION_OPTIONS_ERROR%22,%0A                    %22An unexpected error happened during notification options change:%22 + e.getMessage(), null);%0A        %7D%0A    %7D
 %0A%7D%0A

handle notification changes in Android MethodCallHandler