package com.atmob.map_amap_android.util;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Application;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;

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

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.atmob.map_amap_android.R;

import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

public class AMapHelper {
    private static final String TAG = "AMapHelper";
    public static final String KEY_LAST_TRACK_ID = "amap_last_track_id";
    private static final int AMAP_NOTIFICATION_ID = 350;
    private static final String AMAP_NOTIFICATION_CHANNEL_ID = "amap_notification_channel_id";
    private static final String AMAP_NOTIFICATION_CHANNEL_NAME = "Location Tracking";
    private static final AtomicBoolean isLocationInit = new AtomicBoolean(false);
    private static final ArrayList<OnLocationListener> locationListeners = new ArrayList<>();
    private static AMapLocation lastLocation;
    @SuppressLint("StaticFieldLeak")
    private static AMapLocationClient aMapLocationClient;
    private static final String[] LOCATION_PERMISSION = new String[]{
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
    };

    public static void init(Context context) {
        if (ProcessUtil.isMainProcess(context)) {
            initLocation(context);
        }
    }

    private static void initLocation(Context context) {
        if (isLocationInit.compareAndSet(false, true)) {
            try {
                LogUtil.d(TAG, "amap ... initLocation...");
                AMapLocationClient.updatePrivacyShow(context, true, true);
                AMapLocationClient.updatePrivacyAgree(context, true);
                aMapLocationClient = new AMapLocationClient(context);
                aMapLocationClient.setLocationOption(new AMapLocationClientOption().setInterval(5000));
                aMapLocationClient.setLocationListener(aMapLocation -> {
                    if (aMapLocation != null) {
                        if (aMapLocation.getErrorCode() == 0) {
                            lastLocation = aMapLocation;
                            LogUtil.d(TAG, "onLocationChanged: " + aMapLocation);
                            for (OnLocationListener locationListener : locationListeners) {
                                locationListener.onLocationChanged(aMapLocation);
                            }
                        }
                    }
                });
                if (PermissionUtil.hasPermission(context, LOCATION_PERMISSION)) {
                    aMapLocationClient.startLocation();
                    aMapLocationClient.enableBackgroundLocation(AMAP_NOTIFICATION_ID, createLocationNotification(context));
                }
            } catch (Exception e) {
                isLocationInit.set(false);
                LogUtil.e(TAG, "initLocation failed.", e);
            }
        }
    }

    public static void startLocation(Context context) {
        if (isLocationInit.get()) {
            aMapLocationClient.startLocation();
            aMapLocationClient.enableBackgroundLocation(AMAP_NOTIFICATION_ID, createLocationNotification(context));
        } else {
            initLocation(context);
        }
    }


    private static Notification createLocationNotification(Context context) {
        LogUtil.d(TAG, "amap ... createLocationNotification...");
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Application.NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel notificationChannel = new NotificationChannel(AMAP_NOTIFICATION_CHANNEL_ID,
                    AMAP_NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
            notificationManager.createNotificationChannel(notificationChannel);
        }

        Intent splashIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());

        PendingIntent contentIntent = PendingIntent.getActivity(
                context,
                12345,
                splashIntent,
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
        );

        String appName = SystemUtil.getAppName(context);

        return new NotificationCompat.Builder(context, AMAP_NOTIFICATION_CHANNEL_ID)
                .setContentTitle(context.getString(R.string.location_notification_title, appName))
                .setContentText(context.getString(R.string.location_notification_content, appName))
                .setSmallIcon(R.drawable.icon_location_notification_small)
                .setContentIntent(contentIntent)
                .setOngoing(true)
                .setSilent(true)
                .setAutoCancel(false)
                .build();
    }

    public static AMapLocation getLastLocation() {
        return lastLocation;
    }

    public static void addOnLocationListener(OnLocationListener locationListener) {
        locationListeners.add(locationListener);
    }

    public static void removeOnLocationListener(OnLocationListener locationListener) {
        locationListeners.remove(locationListener);
    }

    public interface OnLocationListener {
        void onLocationChanged(@NonNull AMapLocation aMapLocation);
    }

}