package com.qianmi.hardwarekit.sunmi.scale;

/**
 * Created by xiayinglin on 2017/4/6.
 */


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.sunmi.electronicscaleservice.ScaleCallback;
import com.sunmi.scalelibrary.ScaleManager;

/**
 * Created by cyz.aoj on 2017/1/16.
 */

public class ScaleModule extends ReactContextBaseJavaModule {


    private ScaleManager mScaleManager;
    private BroadcastReceiver mScaleReceiver;
    public static String SCALE_FILTER = "SCALE_FILTER";

    public ScaleModule(ReactApplicationContext reactContext) {
        super(reactContext);

        try {
            mScaleReceiver = new ScaleReceiver();
            IntentFilter filter = new IntentFilter();
            filter.addAction(SCALE_FILTER);
            reactContext.registerReceiver(mScaleReceiver, filter);
        } catch (Exception e) {
            Log.e(this.getClass().getSimpleName(), e.getClass().getSimpleName());
        }
    }

    public class ScaleReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (SCALE_FILTER.equals(action)) {
                final WritableMap params = Arguments.createMap();
                params.putInt("net", intent.getIntExtra("net", 0));
                params.putInt("tare", intent.getIntExtra("tare", 0));
                params.putInt("status", intent.getIntExtra("status", 0));
                ScaleModule.this.event("scale.data", params);
            }
        }
    }

    @ReactMethod
    public void tare() {
        Log.d(getClass().getSimpleName(), "--- tare ---");
        try {
            if (null != mScaleManager) {
                mScaleManager.tare();
            }
        } catch (RemoteException e) {
            Log.e(this.getClass().getSimpleName(), e.getClass().getSimpleName());
        }
    }


    @ReactMethod
    public void zero() {
        Log.d(getClass().getSimpleName(), "--- zero ---");

        try {
            if (null != mScaleManager) {
                mScaleManager.zero();
            }
        } catch (RemoteException e) {
            Log.e(this.getClass().getSimpleName(), e.getClass().getSimpleName());
            e.printStackTrace();
        }
    }


    @ReactMethod
    public void destroy() {
        Log.d(getClass().getSimpleName(), "--- destroy ---");

        try {
            if (null != mScaleManager) {
                getReactApplicationContext().unregisterReceiver(mScaleReceiver);
                mScaleManager.onDestroy();
                mScaleManager = null;
            }
        } catch (Exception e) {
            Log.e(this.getClass().getSimpleName(), e.getClass().getSimpleName());
            e.printStackTrace();
        }
    }


    @ReactMethod
    public void state(Promise promise) {
        Log.d(getClass().getSimpleName(), "--- readSealState ---");

        try {
            final WritableMap params = Arguments.createMap();
            if (null != mScaleManager) {
                params.putInt("value", mScaleManager.readSealState());
                promise.resolve(params);
            }
        } catch (Exception e) {
            promise.reject(e);
            Log.e(this.getClass().getSimpleName(), e.getClass().getSimpleName());
            e.printStackTrace();
        }
    }


    @ReactMethod
    public void getCalStatus(Promise promise) {
        Log.d(getClass().getSimpleName(), "--- getCalStatus ---");

        try {
            final WritableMap params = Arguments.createMap();
            if (null != mScaleManager) {
                params.putInt("value", mScaleManager.getCalStatus());
                promise.resolve(params);
            }
        } catch (Exception e) {
            promise.reject(e);
            Log.e(this.getClass().getSimpleName(), e.getClass().getSimpleName());
            e.printStackTrace();
        }
    }


    @ReactMethod
    public void getData() {
        Log.d(getClass().getSimpleName(), "--- getData ---");

        if (null == mScaleManager) {
            mScaleManager = ScaleManager.getInstance(getReactApplicationContext());
            mScaleManager.connectService(new ScaleManager.ScaleServiceConnection() {
                @Override
                public void onServiceConnected() {
                    getScaleData();
                }

                @Override
                public void onServiceDisconnect() {
                }
            });
        }
    }


    private void getScaleData() {
        try {
            mScaleManager.getData(new ScaleCallback.Stub() {
                @Override
                public void getData(final int net, final int tare, final int status) {
                    Intent finishIntent = new Intent();
                    finishIntent.setAction(SCALE_FILTER);
                    finishIntent.putExtra("net", net);
                    finishIntent.putExtra("tare", tare);
                    finishIntent.putExtra("status", status);
                    getReactApplicationContext().sendBroadcast(finishIntent);
                }
            });
        } catch (RemoteException e) {
            Log.e(this.getClass().getSimpleName(), e.getClass().getSimpleName());
        }
    }


    private void event(String eventName, @Nullable WritableMap params) {
        ReactApplicationContext reactContext = this.getReactApplicationContext();
        if (null != reactContext && reactContext.hasActiveCatalystInstance()) {
            if (null == params) {
                params = Arguments.createMap();
            }
            Log.d(this.getClass().getSimpleName(), "event -> name: " + eventName);
            reactContext
                    .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                    .emit(eventName, params);
        }
    }


    @Override
    public String getName() {
        return "Scale";
    }
}
