package com.qianmi.hardwarekit.sprt;

import android.bluetooth.BluetoothDevice;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;

import com.facebook.react.bridge.Arguments;
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.qianmi.hardwarekit.bluetooth.BluetoothDeviceFinder;
import com.qianmi.hardwarekit.bluetooth.BluetoothModule;
import com.qianmi.hardwarekit.bluetooth.BluetoothThreadPool;
import com.qianmi.hardwarekit.bluetooth.PrinterCommands;
import com.qianmi.hardwarekit.bluetooth.Utils;
import com.qianmi.hardwarekit.sunmi.printer.BytesUtil;

import java.io.UnsupportedEncodingException;

/**
 * Created by xiayinglin on 2017/7/27.
 */
public class SPRTPrintModule extends ReactContextBaseJavaModule {

//    private final static String KEY_CONNECT_CLOSE = "sprt.state.disconnect";
//    private final static String KEY_CONNECT_CONNECT = "sprt.state.connect";

    private BluetoothThreadPool pool = BluetoothThreadPool.instance();

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

    @ReactMethod
    public void disconnect(String address) {
        if (!TextUtils.isEmpty(address)) {
            pool.disconnect(address);
            WritableMap params = Arguments.createMap();
            params.putString("address", address);
            SPRTPrintModule.this.event(BluetoothDeviceFinder.DISCOUNT, params);
        }

    }

    @ReactMethod
    public void connect(String address) {
        if (!TextUtils.isEmpty(address)) {
            disconnect(address);
            Log.d(getClass().getSimpleName(), "connect bluetooth:" + address);
            BluetoothDevice device = pool.connect(address);
            WritableMap params = Arguments.createMap();

            params.putString("address", address);
            params.putString("name", device.getName());
            params.putString("bondState", String.valueOf(BluetoothModule.state(device.getBondState())));
            SPRTPrintModule.this.event(BluetoothDeviceFinder.BONDED, params);
        }
    }

    /**
     * printAlignCenter
     */
    @ReactMethod
    public void printAlignCenter(String address) {
        Log.d(getClass().getSimpleName(), "-- printAlignCenter -- :" + address);
        try {
            if (!TextUtils.isEmpty(address)) {
                pool.write(address, new String(PrinterCommands.ESC_ALIGN_CENTER, "GBK"), "GBK");
            }
        } catch (UnsupportedEncodingException e) {
            Log.e(getClass().getSimpleName(), e.toString());
        }
    }

    /**
     * printAlignLeft
     */
    @ReactMethod
    public void printAlignLeft(String address) {
        Log.d(getClass().getSimpleName(), "-- printAlignLeft --:" + address);
        try {
            if (!TextUtils.isEmpty(address)) {
                pool.write(address, new String(PrinterCommands.ESC_ALIGN_LEFT, "GBK"), "GBK");
            }
        } catch (UnsupportedEncodingException e) {
            Log.e(getClass().getSimpleName(), e.toString());

        }
    }

    /**
     * printAlignRight
     */
    @ReactMethod
    public void printAlignRight(String address) {
        Log.d(getClass().getSimpleName(), "-- printAlignRight --:" + address);
        try {
            if (!TextUtils.isEmpty(address)) {
                pool.write(address, new String(PrinterCommands.ESC_ALIGN_RIGHT, "GBK"), "GBK");
            }
        } catch (UnsupportedEncodingException e) {
            Log.e(getClass().getSimpleName(), e.toString());
        }
    }


    /**
     * printlnText
     */
    @ReactMethod
    public void printText(String address, String text) {
        Log.d(getClass().getSimpleName(), "-- printlnText --:" + address);
        if (!TextUtils.isEmpty(address)) {
            pool.write(address, text, null);
        }
    }

    /**
     * printlnText
     */
    @ReactMethod
    public void printlnText(String address, String text) {
        Log.d(getClass().getSimpleName(), "-- printlnText -- :" + address);
        if (!TextUtils.isEmpty(address)) {
            pool.write(address, text + "\n", null);
        }
    }


    /**
     * lineWrap
     */
    @ReactMethod
    public void lineWrap(String address, Integer nums) {
        Log.d(getClass().getSimpleName(), "-- printlnText -- :" + address);
        if (!TextUtils.isEmpty(address)) {
            for (int index = nums; index >= 0; --index) {
                pool.write(address, "\n", null);
            }
        }

    }

    /**
     * lineSplit
     */
    @ReactMethod
    public void lineSplit(String address) {
        Log.d(getClass().getSimpleName(), "-- printlnText --:" + address);
        if (!TextUtils.isEmpty(address)) {
            pool.write(address, "--------------------------------\n", null);
        }
    }


    /**
     * fontTitle
     */
    @ReactMethod
    public void fontTitle(String address) {
        Log.d(getClass().getSimpleName(), "-- fontTitle --:" + address);
        try {
            if (!TextUtils.isEmpty(address)) {
                pool.write(address, new String(new byte[]{0x1B, 0x21, 0x20}, "GBK"), "GBK");
            }
        } catch (UnsupportedEncodingException e) {
            Log.e(getClass().getSimpleName(), e.toString());
        }

    }

    /**
     * fontContent
     */
    @ReactMethod
    public void fontContent(String address) {
        Log.d(getClass().getSimpleName(), "-- fontContent --:" + address);
        try {
            if (!TextUtils.isEmpty(address)) {
                pool.write(address, new String(new byte[]{0x1B, 0x21, 0x03}, "GBK"), null);
            }
        } catch (UnsupportedEncodingException e) {
            Log.e(getClass().getSimpleName(), e.toString());
        }
    }


    @ReactMethod
    public void printQrCode(String address, String text) {
        byte[] bytes = BytesUtil.getZXingQRCode(text, 360);
        try {
            if (!TextUtils.isEmpty(address)) {
                pool.write(address, new String(bytes, "GBK"), null);
            }
        } catch (UnsupportedEncodingException e) {
            Log.e(getClass().getSimpleName(), e.toString());
        }

    }


    @ReactMethod
    public void printBarCode(String address, String text) {
        try {
            byte[] bytes = Utils.decodeBitmap(Utils.createBarcode(text, 360, 180, true));
            if (!TextUtils.isEmpty(address)) {
                pool.write(address, new String(bytes != null ? bytes : new byte[0], "GBK"), null);
            }
        } catch (UnsupportedEncodingException e) {
            Log.e(getClass().getSimpleName(), e.toString());
        }
    }

    @ReactMethod
    public void printSmallTicket(String address, String bean) {

    }

    @ReactMethod
    public void sendPos(String address, String posCMD) {
        String[] arrPosCmds = posCMD.split(",");
        for (int i = 0; i < arrPosCmds.length; i++) {
            if (!TextUtils.isEmpty(arrPosCmds[i])) {
                pool.write(address, arrPosCmds[i] + "\r\n", "GBK");
            }
        }
    }

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


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