package com.aplusinformatique.aplusmanager.Activitys;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;

import com.aplusinformatique.aplusmanager.R;
import com.sygic.sdk.remoteapi.Api;
import com.sygic.sdk.remoteapi.ApiCallback;
import com.sygic.sdk.remoteapi.ApiNavigation;
import com.sygic.sdk.remoteapi.events.ApiEvents;
import com.sygic.sdk.remoteapi.exception.GeneralException;
import com.sygic.sdk.remoteapi.exception.NavigationException;
import com.sygic.sdk.remoteapi.model.WayPoint;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class SygicStandaloneApiActivity extends AppCompatActivity {

    private static final String TAG = "distrimobilelog_StandaloneSYGIC";

    //Constants
    //Broadcast de retour
    public final static String ACTION_RESPONSE = "com.aplusinformatique.aplusmanager.sygicstandaloneresponse";
    private final static String INTENT_PARAMETER_STATUS_CODE = "status_code";
    private final static String INTENT_PARAMETER_STATUS_MESSAGE = "status_message";
    private final static String STATUS_CODE_OK = "000";
    private final static String STATUS_CODE_PARAMETER_LOCATION_ERROR = "001";
    private final static String STATUS_CODE_PARAMETER_JSON_ERROR = "001";
    private final static String STATUS_CODE_CALLBACK_ERROR = "101";
    private final static String STATUS_CODE_SYGIC_APP_NOT_RUNNING = "102";
    private final static String STATUS_CODE_MAP_NOT_SHOWING = "103";
    private final static String STATUS_CODE_NAVIGATION_ERROR = "104";

    private final static String NAVIGATION_RESULT_SUCCESS = "navigation_result_success";

    //Paramètres JSON
    public final static String JSON_NAVIGATION = "navigation";
    public final static String JSON_NAVIGATION_ADDRESS = "address";
    public final static String JSON_NAVIGATION_LATITUDE = "latitude";
    public final static String JSON_NAVIGATION_LONGITUDE = "longitude";

    //Navigation to parameters
    private String prmAddress = "";
    private double prmLatitude = 0;
    private double prmLongitude = 0;

    //SYGIC object
    private Api mApi;
    private ApiCallback mApiCallback;
    Handler eventHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sygic_standalone_api);

        Intent intent = getIntent();

//        if (intent.getExtras() != null) {
//            if (intent.getExtras().containsKey("address")) {
//                prmAddress = intent.getExtras().getString("address");
//                Log.d(TAG, "onCreate : address : " + prmAddress);
//            }
//        }
//
//        if (intent.getExtras() != null) {
//            if (intent.getExtras().containsKey("latitude")) {
//                prmLatitude = Double.parseDouble(intent.getExtras().getString("latitude"));
//                Log.d(TAG, "onCreate : latitude : " + Double.toString(prmLatitude));
//            }
//        }
//
//        if (intent.getExtras() != null) {
//            if (intent.getExtras().containsKey("longitude")) {
//                prmLongitude = Double.parseDouble(intent.getExtras().getString("longitude"));
//                Log.d(TAG, "onCreate : longitude : " + Double.toString(prmLongitude));
//            }
//        }

        boolean hasParametersError = false;
        try {
            JSONObject jObject = new JSONObject(intent.getExtras().getString("jsonParameters"));

            prmAddress = jObject.getJSONObject(JSON_NAVIGATION).getString(JSON_NAVIGATION_ADDRESS);
            prmLatitude = jObject.getJSONObject(JSON_NAVIGATION).getDouble(JSON_NAVIGATION_LATITUDE);
            prmLongitude = jObject.getJSONObject(JSON_NAVIGATION).getDouble(JSON_NAVIGATION_LONGITUDE);

            Log.d(TAG, "onCreate : address : " + prmAddress);
            Log.d(TAG, "onCreate : latitude : " + Double.toString(prmLatitude));
            Log.d(TAG, "onCreate : longitude : " + Double.toString(prmLongitude));
//                    JSONArray jArray = jObject.getJSONArray(JSON_NAVIGATION);
//
//                    // If the list is empty, then clean all.
//                    if (jArray != null) {
//
//                        for (int i = 0; i < jArray.length(); i++) {
//                            try {
//                                JSONObject currentGeofenceJSON = jArray.getJSONObject(i);
//                                // Get the parameters value
//                                String paramId = currentGeofenceJSON.getString(JSON_PARAM_GEOFENING_ID);
//                                double paramLatitude = currentGeofenceJSON.getDouble(JSON_PARAM_GEOFENING_LATITUDE);
//                                double paramLongitude = currentGeofenceJSON.getDouble(JSON_PARAM_GEOFENING_LONGITUDE);
//                                float paramRadius = (float) currentGeofenceJSON.getDouble(JSON_PARAM_GEOFENING_RADIUS);
//                                long paramWarningDelay = currentGeofenceJSON.getLong(JSON_PARAM_GEOFENING_WARNING_DELAY);
//                                long paramCheckDelay = currentGeofenceJSON.getLong(JSON_PARAM_GEOFENING_CHECK_DELAY);
//                                String routingApi = currentGeofenceJSON.getString(JSON_PARAM_GEOFENING_ROUTING_API);
//
//
//                                if (BuildConfig.DEBUG || true) {
//                                    Log.d(TAG, "onReceive ACTION_GEOFENCING id " + paramId);
//                                    Log.d(TAG, "onReceive ACTION_GEOFENCING latitude " + paramLatitude);
//                                    Log.d(TAG, "onReceive ACTION_GEOFENCING longitude " + paramLongitude);
//                                    Log.d(TAG, "onReceive ACTION_GEOFENCING radius " + paramRadius);
//                                    Log.d(TAG, "onReceive ACTION_GEOFENCING warning_delay " + paramWarningDelay);
//                                    Log.d(TAG, "onReceive ACTION_GEOFENCING check_delay " + paramCheckDelay);
//                                    Log.d(TAG, "onReceive ACTION_GEOFENCING routing_api " + routingApi);
//                                }
//
//                            } catch (JSONException e) {
//                                // Oops
//                                e.printStackTrace();
//
//                                return "Erreur JSON : " + e.getMessage();
//                            }
//                        }
//                    }
        } catch (JSONException e) {
            hasParametersError = true;
            sendResponse(getApplicationContext(), STATUS_CODE_PARAMETER_JSON_ERROR, e.toString());
            Log.e(TAG, e.toString());
        } catch (NullPointerException e) {
            hasParametersError = true;
            sendResponse(getApplicationContext(), STATUS_CODE_PARAMETER_JSON_ERROR, e.toString());
            Log.e(TAG, e.toString());
        }

        if (hasParametersError == false && (prmLatitude == 0 || prmLongitude == 0)) {
            hasParametersError = true;
            sendResponse(getApplicationContext(), STATUS_CODE_PARAMETER_LOCATION_ERROR, "Latitude/Longitude required");
        }

        if (hasParametersError == false) {
            initializeSygic();
        }
    }

    private void initializeSygic() {

        mApiCallback = new ApiCallback() {

            @Override
            public void onServiceDisconnected() {
                Log.d(TAG,"RemoteAPI onServiceDisconnected");
            }

            @Override
            public void onServiceConnected() {
                Log.d(TAG,"RemoteAPI onServiceConnected");

                try {
                    mApi.registerCallback();
                } catch (RemoteException e) {
                    sendResponse(getApplicationContext(),STATUS_CODE_CALLBACK_ERROR, e.toString());
                }

                try {
                    boolean isRun = Api.isApplicationRunning(1000);
                    if (isRun) {
                        Log.d(TAG,"Application SYGIC already running");
                    } else {
                        Log.d(TAG,"Application SYGIC not running");
                    }

                    try {
                        mApi.show(false);
                    } catch (RemoteException e) {
                        sendResponse(getApplicationContext(),STATUS_CODE_MAP_NOT_SHOWING, e.toString());
                    }

                    if (isRun) {
                        launchNavigation();
                    }

                } catch (GeneralException e) {
                    sendResponse(getApplicationContext(),STATUS_CODE_SYGIC_APP_NOT_RUNNING, e.toString());
                }
            }

            @Override
            public void onEvent(int event, String data) {
                eventHandler.obtainMessage(event, data).sendToTarget();
            }
        };

        eventHandler = new Handler(new Handler.Callback() {

            @Override
            public boolean handleMessage(Message msg) {
                int event = msg.what;
                String data = (String)msg.obj;
                if (event == ApiEvents.EVENT_APP_STARTED)
                {
                    Log.d(TAG,"Application SYGIC started");
                    launchNavigation();
                }
                if (event == ApiEvents.EVENT_APP_EXIT)
                {
                    Log.d(TAG,"Application SYGIC exited");
                    finish();
                }

                return false;
            }
        });

        mApi = Api.init(getApplicationContext(), "com.sygic.truck", "com.sygic.truck.SygicService", mApiCallback);
        mApi.connect();
    }

    private void launchNavigation() {
        Log.d(TAG,"lauching navigation, navigate to : latitude : " + prmLatitude + " longitude : " + prmLongitude);
        String navigationResult = navigateToCoordinate(prmLatitude, prmLongitude);
        Log.d(TAG, "Navigation result : " + navigationResult);
        if (navigationResult == NAVIGATION_RESULT_SUCCESS) {
            sendResponse(getApplicationContext(), STATUS_CODE_OK, "");
        } else {
            sendResponse(getApplicationContext(),STATUS_CODE_NAVIGATION_ERROR, navigationResult);
        }
    }

    private void sendResponse(Context context, String statusCode, String statusMessage) {

        Intent intent = new Intent();
        intent.setAction(ACTION_RESPONSE);
        intent.putExtra(INTENT_PARAMETER_STATUS_CODE, statusCode);
        intent.putExtra(INTENT_PARAMETER_STATUS_MESSAGE, statusMessage);

        context.sendBroadcast(intent);

        finish();
    }

    private String navigateToCoordinate(double lat, double lon)
    {
        int x = (int)(lon * 100000);
        int y = (int)(lat * 100000);
        WayPoint wp = new WayPoint("B", x, y);
        try {
            ApiNavigation.startNavigation(wp, 0, false, 0);
        } catch (NavigationException e) {
            return e.getMessage() + "/" + e.getCode();
        }

        return NAVIGATION_RESULT_SUCCESS;
    }

    @Override
    protected void onDestroy() {
        Log.d(TAG,"onDestroy");
        try {
            mApi.unregisterCallback();
            mApi.disconnect();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        super.onDestroy();
    }
}
