package com.atmob.map_amap_android;

import androidx.annotation.NonNull;

import com.amap.api.location.AMapLocation;
import com.atmob.map_amap_android.contants.Constants;
import com.atmob.map_amap_android.util.AMapHelper;
import com.atmob.map_amap_android.util.LogUtil;

import java.util.HashMap;
import java.util.Map;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.EventChannel;

public class FlutterLocationEventPlugin implements FlutterPlugin, EventChannel.StreamHandler, AMapHelper.OnLocationListener {

    private static final String TAG = "FlutterLocationEventPlugin";

    private EventChannel eventChannel;
    private EventChannel.EventSink eventSink;
    private Map<String, Object> locationMap;

    @Override
    public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
        eventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), Constants.MAP_LOCATION_EVENT_CHANNEL);
        eventChannel.setStreamHandler(this);
        AMapHelper.addOnLocationListener(this);
    }

    @Override
    public void onDetachedFromEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
        if (eventChannel != null) {
            eventChannel.setStreamHandler(null);
        }
        AMapHelper.removeOnLocationListener(this);
        eventChannel = null;
        eventSink = null;
        locationMap.clear();
        locationMap = null;
    }

    @Override
    public void onListen(Object o, EventChannel.EventSink eventSink) {
        this.eventSink = eventSink;
    }

    @Override
    public void onCancel(Object o) {
        eventSink = null;
        locationMap.clear();
        locationMap = null;
    }

    @Override
    public void onLocationChanged(@NonNull AMapLocation aMapLocation) {
        senLocation(aMapLocation);
    }


    private void senLocation(AMapLocation mapLocation) {
        try {
            if (eventSink != null) {
                eventSink.success(location2Map(mapLocation));
                LogUtil.d(TAG, "senLocation success: " + mapLocation);
            }
        } catch (Exception e) {
            LogUtil.d(TAG, "senLocation error: " + e.getMessage());
            sendError("-1", e.getMessage());
        }
    }

    private void sendError(String errorCode, String errorMessage) {
        if (eventSink != null) {
            eventSink.error(errorCode, errorMessage, null);
        }
    }

    private Map<String, Object> location2Map(AMapLocation location) {
        if (locationMap == null) {
            locationMap = new HashMap<>(7);
        }
        locationMap.clear();
        locationMap.put("errorCode", location.getErrorCode());
        locationMap.put("latitude", location.getLatitude());
        locationMap.put("longitude", location.getLongitude());
        locationMap.put("address", location.getAddress());
        locationMap.put("time", location.getTime());
        locationMap.put("speed", location.getSpeed());
        locationMap.put("bearing", location.getBearing());
        return locationMap;
    }
}
