/**
 * Copyright (c) 2017-present, Stanislav Doskalenko - doskalenko.s@gmail.com
 * All rights reserved.
 *
 * This source code is licensed under the MIT-style license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * Based on Asim Malik android source code, copyright (c) 2015
 *
 **/
package com.reactnative.googlefit;

import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;

import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.fitness.Fitness;


public class GoogleFitManager implements
        ActivityEventListener {

    private ReactContext mReactContext;
    private GoogleApiClient mApiClient;
    private static final int REQUEST_OAUTH = 1;
    private static final String AUTH_PENDING = "auth_state_pending";
    private boolean authInProgress = false;
    private Activity mActivity;

    private DistanceHistory distanceHistory;
    private StepHistory stepHistory;
    private WeightsHistory weightsHistory;
    private StepCounter mStepCounter;
    private StepSensor stepSensor;

    private static final String TAG = "RNGoogleFit";

    public GoogleFitManager(ReactContext reactContext, Activity activity) {

        //Log.i(TAG, "Initializing GoogleFitManager" + authInProgress);
        this.mReactContext = reactContext;
        this.mActivity = activity;


        mReactContext.addActivityEventListener(this);


        this.mStepCounter = new StepCounter(mReactContext, this, activity);
        this.stepHistory = new StepHistory(mReactContext, this);
        this.weightsHistory = new WeightsHistory(mReactContext, this);
        this.distanceHistory = new DistanceHistory(mReactContext, this);

//        this.stepSensor = new StepSensor(mReactContext, activity);
    }

    public GoogleApiClient getGoogleApiClient() {
        return mApiClient;
    }

    public StepCounter getStepCounter() {
        return mStepCounter;
    }

    public StepHistory getStepHistory() {
        return stepHistory;
    }

    public WeightsHistory getWeightsHistory() {
        return weightsHistory;
    }

    public DistanceHistory getDistanceHistory() {
        return distanceHistory;
    }

    public void authorize(@Nullable final Callback errorCallback, @Nullable final Callback successCallback) {

        //Log.i(TAG, "Authorizing");
        mApiClient = new GoogleApiClient.Builder(mReactContext.getApplicationContext())
                .addApi(Fitness.SENSORS_API)
                .addApi(Fitness.HISTORY_API)
                .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ))
                .addScope(new Scope(Scopes.FITNESS_BODY_READ_WRITE))
                .addScope(new Scope(Scopes.FITNESS_LOCATION_READ))
                .addConnectionCallbacks(
                    new GoogleApiClient.ConnectionCallbacks() {
                        @Override
                        public void onConnected(@Nullable Bundle bundle) {
                            Log.i(TAG, "Authorization - Connected");

                            //sendEvent(this.mReactContext, "AuthorizeEvent", map);
                            if (successCallback != null) {
                                WritableMap map = Arguments.createMap();
                                map.putBoolean("authorized", true);
                                successCallback.invoke(map);
                            }
                        }

                        @Override
                        public void onConnectionSuspended(int i) {
                            Log.i(TAG, "Authorization - Connection Suspended");
                            if ((mApiClient != null) && (mApiClient.isConnected())) {
                                mApiClient.disconnect();
                            }
                        }
                    }
                )
                .addOnConnectionFailedListener(
                    new GoogleApiClient.OnConnectionFailedListener() {
                        @Override
                        public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
                            Log.i(TAG, "Authorization - Failed Authorization Mgr:" + connectionResult);
                            if (authInProgress) {
                                //if (errorCallback != null) {
                                //    errorCallback.invoke("Failed Authorization Mgr");
                                //}
                            } else {
                                try {
                                    authInProgress = true;
                                    connectionResult.startResolutionForResult(mActivity, REQUEST_OAUTH);
                                } catch (IntentSender.SendIntentException e) {
                                    Log.i(TAG, "Authorization - Failed again: " + e);
                                }
                            }
                        }
                    }
                )
                .build();

        mApiClient.connect();
    }

    public boolean isAuthorize() {
        if (mApiClient != null && mApiClient.isConnected()) {
            return true;
        } else {
            return false;
        }
    }

    protected void stop() {
        Fitness.SensorsApi.remove(mApiClient, mStepCounter)
                .setResultCallback(new ResultCallback<Status>() {
                    @Override
                    public void onResult(Status status) {
                        if (status.isSuccess()) {
                            mApiClient.disconnect();
                        }
                    }
                });
    }


    private void sendEvent(ReactContext reactContext,
                           String eventName,
                           @Nullable WritableMap params) {
        reactContext
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit(eventName, params);
    }


    @Override
    public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
        //Log.i(TAG, "onActivityResult" + requestCode);
        if (requestCode == REQUEST_OAUTH) {
            authInProgress = false;
            if (resultCode == Activity.RESULT_OK) {
                if (!mApiClient.isConnecting() && !mApiClient.isConnected()) {
                    mApiClient.connect();
                }
            } else if (resultCode == Activity.RESULT_CANCELED) {
                //Log.e(TAG, "RESULT_CANCELED");
                this.authorize(null, null);
                //mApiClient.connect();
            }
        } //else {
        //Log.e(TAG, "requestCode NOT request_oauth");
        //}

    }

    @Override
    public void onNewIntent(Intent intent) {

    }
}

@@ -1532,17 +1532,18 @@
 boolean 
-a
+mA
 uthInPro
@@ -1975,17 +1975,18 @@
 ager%22 + 
-a
+mA
 uthInPro
@@ -2072,17 +2072,16 @@
 ivity;%0A%0A
-%0A
         
@@ -2127,17 +2127,16 @@
 this);%0A%0A
-%0A
         
@@ -4928,17 +4928,18 @@
     if (
-a
+mA
 uthInPro
@@ -5237,33 +5237,34 @@
                 
-a
+mA
 uthInProgress = 
@@ -6762,34 +6762,32 @@
 data) %7B%0A        
-//
 Log.i(TAG, %22onAc
@@ -6798,16 +6798,18 @@
 tyResult
+: 
 %22 + requ
@@ -6858,24 +6858,25 @@
 ST_OAUTH) %7B%0A
+%0A
             
@@ -6875,17 +6875,18 @@
         
-a
+mA
 uthInPro
@@ -7201,24 +7201,24 @@
 CANCELED%22);%0A
-
             
@@ -7217,24 +7217,26 @@
             
+//
 this.authori

allow cancel