package com.rn_bxl;

import android.widget.Toast;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.JavaOnlyArray;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.Promise;

import com.bixolon.mpos.MPosControllerConfig;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableNativeArray;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MPosControllerConfigProxy extends ReactContextBaseJavaModule {

    private static final String TAG = MPosControllerConfigProxy.class.getSimpleName();
    private MPosControllerConfig mPosControllerConfig;
    private String error  = "test-error";

    public MPosControllerConfigProxy(ReactApplicationContext reactContext) {
        super(reactContext);
        mPosControllerConfig = new MPosControllerConfig();
    }

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

    @ReactMethod
    public void searchDevices(Promise promise){
        try{
            int[] ret = mPosControllerConfig.searchDevices();
            WritableArray rnRet = new WritableNativeArray();
            for(int i=0; i<ret.length; i++){
                rnRet.pushInt(ret[i]);
            }
            promise.resolve(rnRet);
        }catch(Exception e){
            Toast.makeText(getReactApplicationContext(),e.toString(),Toast.LENGTH_SHORT).show();
            promise.reject(error);
        }
    }

    @ReactMethod
    public void getBgateSerialNumber(Promise promise){
        try{
            byte[] ret = mPosControllerConfig.getBGateSerialNumber();
            promise.resolve(new String(ret));
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void selectInterface(int interfaceType, String address, Promise promise){
        try{
            long ret = mPosControllerConfig.selectInterface(interfaceType,address);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void selectCommandMode(int commandMode, Promise promise){
        try{
            long ret = mPosControllerConfig.selectCommandMode(commandMode);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void openService(int deviceID, int timeout, Promise promise){
        try{
            long ret = mPosControllerConfig.openService(deviceID, timeout, getReactApplicationContext());
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void closeService(int timeout, Promise promise){
        try{
            long ret = mPosControllerConfig.closeService(timeout);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void isOpen(Promise promise){
        try{
            Boolean ret = mPosControllerConfig.isOpen();
            int intret;
            if(ret == true){
                intret = 1;
            }else{
                intret = 0;
            }
            promise.resolve(intret);
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void getDeviceId(Promise promise){
        try{
            long ret = mPosControllerConfig.getDeviceId();
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void directIO(ReadableArray data, Promise promise) {
        try{
            byte[] bytes = new byte[data.size()];

            for (int i = 0; i < data.size(); i ++) {
                bytes[i] = (byte) data.getInt(i);
            }

            long ret = mPosControllerConfig.directIO(bytes);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void setTransaction(int mode,Promise promise){
        try{
            long ret = mPosControllerConfig.setTransaction(mode);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void setReadMode(int mode,Promise promise){
        try{
            long ret = mPosControllerConfig.setReadMode(mode);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void getUSBDevice(int deviceID, Promise promise){
        try{
            String ret = mPosControllerConfig.getUSBDevice(deviceID);
            promise.resolve(ret);
        }catch(Exception e){
            promise.reject(e.getMessage());
        }
    }

    @ReactMethod
    public void getCustomDevices(int deviceType, Promise promise){
        try{
            String ret = mPosControllerConfig.getCustomDeviceList(deviceType);
            promise.resolve(ret);
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void addCustomDevice(int deviceType,String vid, String pid, Promise promise){
        try{
            ByteBuffer deviceBuf = ByteBuffer.allocate(4);
            deviceBuf.put(new java.math.BigInteger(vid.substring(0, 2), 16).toByteArray());
            deviceBuf.put(new java.math.BigInteger(vid.substring(2, 4), 16).toByteArray());
            deviceBuf.put(new java.math.BigInteger(pid.substring(0, 2), 16).toByteArray());
            deviceBuf.put(new java.math.BigInteger(pid.substring(2, 4), 16).toByteArray());

            long ret = mPosControllerConfig.addCustomDevice(deviceType, deviceBuf.get(0), deviceBuf.get(1), deviceBuf.get(2), deviceBuf.get(3));
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void deleteCustomDevice(int deviceType,String vid, String pid, Promise promise){
        try{
            ByteBuffer deviceBuf = ByteBuffer.allocate(4);
            deviceBuf.put(new java.math.BigInteger(vid.substring(0, 2), 16).toByteArray());
            deviceBuf.put(new java.math.BigInteger(vid.substring(2, 4), 16).toByteArray());
            deviceBuf.put(new java.math.BigInteger(pid.substring(0, 2), 16).toByteArray());
            deviceBuf.put(new java.math.BigInteger(pid.substring(2, 4), 16).toByteArray());
            long ret = mPosControllerConfig.deleteCustomDevice(deviceType, deviceBuf.get(0), deviceBuf.get(1), deviceBuf.get(2), deviceBuf.get(3));
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void reInitCustomDeviceType(int deviceType, Promise promise){
        try{
            long ret = mPosControllerConfig.resetCustomDeviceList(deviceType);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void getSerialConfig(int deviceId, Promise promise){
        try{
            byte[] ret = mPosControllerConfig.getSerialConfiguration(deviceId);
            WritableArray rnRet = new WritableNativeArray();
            for(int i=0; i<ret.length; i++){
                rnRet.pushInt((int)ret[i]);
            }
            promise.resolve(rnRet);
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void getSerialConfiguration(int deviceId, Promise promise){
        try{
            byte[] ret = mPosControllerConfig.getSerialConfiguration(deviceId);
            WritableArray rnRet = new WritableNativeArray();
            for(int i=0; i<ret.length; i++){
                rnRet.pushInt((int)ret[i]);
            }
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void setSerialConfig(int deviceId, int baudRate, int dataBit, int stopBit, int parityBit, int flowControl, Promise promise){
        try{
            long ret = mPosControllerConfig.setSerialConfiguration(deviceId, (byte)baudRate, (byte)dataBit, (byte)stopBit, (byte)parityBit, (byte)flowControl);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void setSerialConfiguration(int deviceId, int baudRate, int dataBit, int stopBit, int parityBit, int flowControl, Promise promise){
        try{
            long ret = mPosControllerConfig.setSerialConfiguration((byte)deviceId, (byte)baudRate, (byte)dataBit, (byte)stopBit, (byte)parityBit, (byte)flowControl);
            promise.resolve((int)ret);
        }catch(Exception e){
            promise.reject(error);
        }
    }

    @ReactMethod
    public void getSerialNumber(int deviceId, Promise promise){
        try{
            byte[] ret = mPosControllerConfig.getDeivceSerialNumber(deviceId);
            promise.resolve(new String(ret));
        }catch(Exception e){
            promise.reject(error);
        }
    }

    

}

