package com.qianmi.hardwarekit.bluetooth;


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


import android.Manifest;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
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.ReadableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeArray;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.qianmi.hardwarekit.R;
import com.qianmi.hardwarekit.sprt.SPRTPrintModule;

import java.io.UnsupportedEncodingException;
import java.util.Timer;
import java.util.TimerTask;

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

public class BluetoothModule extends ReactContextBaseJavaModule {

    private BluetoothThreadPool pool = BluetoothThreadPool.instance();

    private BluetoothDeviceFinder mFinder;

    public BluetoothModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    private TimerTask cancelTask = new TimerTask() {
        public void run() {
            //execute the task
            Log.d(BluetoothModule.this.getName(), "---- auto cancelDiscovery ----");
            mFinder.cancelDiscovery();
        }
    };

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


    @ReactMethod
    public void create() {
        Log.d(getClass().getSimpleName(), "---- create bluetooth module ----");
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (null == bluetoothAdapter) {
            Log.d(getClass().getSimpleName(), "---- bluetooth off ----");
            return;
        }

        if (bluetoothAdapter.isEnabled()) {
//            mFinder = BluetoothDeviceFinder.me().from(this.getReactApplicationContext());
            if (null == mFinder) {
                mFinder = BluetoothDeviceFinder.me().from(this.getReactApplicationContext());
            } else {
                mFinder.unReceiver();
                mFinder.from(this.getReactApplicationContext());
            }
            return;
        }
        Log.d(getClass().getSimpleName(), "---- check bluetooth ----");
        AlertDialog.Builder builder = new AlertDialog.Builder(this.getCurrentActivity());
        builder.setMessage(R.string.open_bluetooth_setting)
                .setTitle(R.string.warning).setPositiveButton(R.string.setting, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.d(this.getClass().getSimpleName(), "---- toBluetooth ----");
                toBluetooth();
            }
        }).setNegativeButton(R.string.setting_afterNow, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
            }
        });
        builder.create().show();
    }

    @ReactMethod
    public void toBluetooth() {
        Log.d(this.getName(), "---- setting ----");
        Intent intent = new Intent();
        intent.setAction(Settings.ACTION_BLUETOOTH_SETTINGS);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        BluetoothModule.this.getReactApplicationContext().startActivity(intent);
    }

    /**
     * 设备发现
     *
     * @param promise
     */
    @ReactMethod
    public void discovery(Promise promise) {
        if (null == mFinder) {
            BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            if (null != bluetoothAdapter && bluetoothAdapter.isEnabled()) {
                mFinder = BluetoothDeviceFinder.me().from(this.getReactApplicationContext());
                new Timer().schedule(cancelTask, 30 * 1000);
            } else {
                promise.reject("-1", getReactApplicationContext().getString(R.string.open_bluetooth_setting));
                return;
            }
        }
        WritableMap result = Arguments.createMap();
        try {
            result.putBoolean("value", mFinder.discovery());
        } catch (Exception e) {
            Log.d(this.getName(), e.getLocalizedMessage());
            result.putBoolean("value", false);
        }
        promise.resolve(result);
        Log.d(this.getName(), "---- discovery ----");
    }

    /**
     * 设备匹配
     *
     * @param address
     * @param promise
     */
    @ReactMethod
    public void bond(String address, Promise promise) {
        if (null == mFinder) {
            promise.reject("-1", getReactApplicationContext().getString(R.string.open_bluetooth_setting));
            return;
        }
        WritableMap result = Arguments.createMap();
        result.putBoolean("value", mFinder.bonded(address));
        promise.resolve(result);
        Log.d(this.getName(), "---- bond ----");
    }

    @ReactMethod
    public void removeBond(String address, Promise promise) {
        if (null == mFinder) {
            promise.reject("-1", getReactApplicationContext().getString(R.string.open_bluetooth_setting));
            return;
        }
        WritableMap result = Arguments.createMap();
        result.putBoolean("value", mFinder.removeBond(address));
        promise.resolve(result);
        Log.d(this.getName(), "---- removeBond ----");
    }

    @ReactMethod
    public void cancelDiscovery(Promise promise) {
        if (null == mFinder) {
            promise.reject("-1", getReactApplicationContext().getString(R.string.open_bluetooth_setting));
            return;
        }
        WritableMap result = Arguments.createMap();
        result.putBoolean("value", mFinder.cancelDiscovery());
        promise.resolve(result);
        Log.d(this.getName(), "---- cancelDiscovery ----");
    }

    @ReactMethod
    public void disconnect(String address) {
        Log.d(getClass().getSimpleName(), "disconnect bluetooth:" + address);
        pool.disconnect(address);
    }

    @ReactMethod
    public void connect(String address) {
        disconnect(address);
        Log.d(getClass().getSimpleName(), "connect bluetooth:" + address);
        pool.connect(address);
    }


    @ReactMethod
    public void write(String address, String text, String charset) {
        disconnect(address);
        pool.write(address, text, charset);
    }


    /**
     * 销毁
     */
    @ReactMethod
    public void destroy() {
        if (null == mFinder) return;
        mFinder.destroy();
//        mFinder = null;
        Log.d(this.getName(), "---- destroy ----");
    }


    /**
     * 获取已配对的产品
     *
     * @param promise
     */
    @ReactMethod
    public void paired(Promise promise) {
        try {
            WritableMap result = Arguments.createMap();
            WritableArray array = new WritableNativeArray();
            for (BluetoothDevice d : mFinder.paired()) {
                WritableMap device = Arguments.createMap();
                device.putString("name", d.getName());
                device.putString("address", d.getAddress());
                device.putString("bondState", String.valueOf(state(d.getBondState())));
                array.pushMap(device);
            }
            result.putArray("value", array);
            promise.resolve(result);
        } catch (Exception e) {
            promise.reject("-1", e.getMessage());
        }

        Log.d(this.getName(), "---- paired ----");
    }


    public static int state(int bondState) {
        int state = -1;
        switch (bondState) {
            case BluetoothDevice.BOND_BONDED:
                state = 0;
                break;
            case BluetoothDevice.BOND_BONDING:
                state = -1;
                break;
        }
        return state;
    }
}