package com.esl.lib;

import android.app.Activity;
import android.content.Context;

import org.apache.cordova.*;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException;

import extras.Activation;
import extras.App;
import extras.BluetoothList;
import facade.PayPadManager;
import models.messaging.nibss.Globals;
import android.content.Intent;
import android.widget.Toast;
import android.app.Activity;
import models.messaging.nibss.HSMClient;
import emv.controllers.EmvTransactionProcesssor;
import extras.ReferenceList;
import java.text.DecimalFormat;
import android.content.res.AssetManager;
import android.content.IntentFilter;
import extras.BluetoothBroadCastReceiver;
import android.bluetooth.BluetoothDevice;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothAdapter;
import utils.Mail;
import utils.BluetoothService;
import android.telephony.SmsManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.content.ComponentName;
import utils.PrintModel;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import emv.controllers.EmvReversalProcessor;
import android.os.Handler;
import java.util.ArrayList;


public class PaypadFacade extends CordovaPlugin {

    private PayPadManager payPadManager;
    private BluetoothList bluetoothList;
    public static CallbackContext callbackContext;
    private CordovaPlugin activityResultCallback;
    private static Activity activity;
    private static JSONArray arrays;
    public static Context activityContext;
    public static final int REQUEST_ENABLE_BT_M = 3;
    public static final int REQUEST_ENABLE_BT_M_PRINTER = 4;
    public static String tempAddress = "", address = "";
    public static String printerAddress = "", lastKnowPrinter = "";
    public static String DEVICE_ADDRESS = "device_name";

    private BluetoothService mService = null;
    private boolean mBounded;

    private BroadcastReceiver mStateReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

//            Log.i(TAG, action);
            if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
                BluetoothService.closePinter();
            }
        }
    };


    BluetoothBroadCastReceiver mReceiver = new BluetoothBroadCastReceiver();
    static BluetoothProfile.ServiceListener serviceListener;



    ServiceConnection mConnection = new ServiceConnection() {

        public void onServiceDisconnected(ComponentName name) {

            // Toast.makeText(CheckPassword.this, "Service is disconnected",
            // Toast.LENGTH_SHORT).show();
            mBounded = false;
            mService = null;
        }

        public void onServiceConnected(ComponentName name, IBinder service) {

            mBounded = true;
            BluetoothService.LocalBinder mLocalBinder = (BluetoothService.LocalBinder) service;
            mService = mLocalBinder.getService();
        }
    };

    /**
     * Called when the activity is becoming visible to the user.
     */
    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {

        arrays = args;
        this.callbackContext = callbackContext;
        final CallbackContext callbackContext2 = callbackContext;
        activity = cordova.getActivity();

        if (action.equals("list")){

            try {

                Context context = this.cordova.getActivity().getApplicationContext();
                activityContext = this.cordova.getActivity();

                if(context == null){

                    callbackContext.error("Context is null");
                    return true;
                    // System.out.println("Context is null");
                }else{
                    System.out.println("Context is not null");
                }

                bluetoothList = new BluetoothList();

                JSONObject response = bluetoothList.updateDeviceList();
                callbackContext.success(response);

            } catch (Exception e){
                callbackContext.error("Failed to parse parameters "+ e.getMessage());
            }
            return true;

        } else if (action.equals("activation")){

            try {
                Activation activation = new Activation();
                JSONObject response = activation.doActivation(args.getString(0));

                boolean status = response.optBoolean("status");

                if (status){
                    callbackContext.success(response);

                }else{
                    callbackContext.error("Invalid Activation Code");
                }
                if (response==null){
                    callbackContext.error("Please, try again. Server cannot be reached");
                }

            } catch (JSONException e){
                callbackContext.error("Failed to parse parameters");
            }
            return true;

        } else if (action.equals("initialization")){
            try {

                Globals.merchantTerminalID = args.getString(0);
                // String stateVas = args.getString(1);

                Globals.doVas =  args.getBoolean(1); //Boolean.getBoolean(stateVas);

                //showToast(Globals.doVas+" DO VAS");

                // showToast("merchantTerminalID : "+Globals.merchantTerminalID);
                PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
                r.setKeepCallback(true);
                callbackContext.sendPluginResult(r);

                Context context = this.cordova.getActivity();
                ReferenceList.config = context.getSharedPreferences(
                    Globals.preference, 0);
                String address = ReferenceList.config.getString(Globals.bluetoothAddressKey,"");
                JSONObject obj = new JSONObject();
                obj.put("operation","initialization");

                if(address.equalsIgnoreCase(Globals.bluetoothAddress)) {

                    obj.put("status","Already_initialised");
                    r = new PluginResult(PluginResult.Status.OK, obj);
                    r.setKeepCallback(false);
                    callbackContext.sendPluginResult(r);

                    // showToast("Already initialised");
                    return true;
                } 


                Intent hsmService = new Intent(cordova.getActivity(),HSMClient.class);
                cordova.getActivity().startService(hsmService);

                //showToast(address +" : "+Globals.bluetoothAddress);

            } catch (Exception e){
                // callbackContext.error("Failed to parse parameters "+ e.getMessage());
                callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, "Error - "+e.getMessage()));

            }
            return true;

        } else if (action.equals("connection")){

            try {                
                // This ensure that the application waits for the result
                PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
                r.setKeepCallback(true);
                callbackContext.sendPluginResult(r);

                Context context = this.cordova.getActivity();
                ReferenceList.config = context.getSharedPreferences(
                    Globals.preference, 0);

                BluetoothAdapter.getDefaultAdapter().getProfileProxy(context, serviceListener, BluetoothProfile.A2DP);

                address = ReferenceList.config.getString(Globals.bluetoothAddressKey,"");

                tempAddress = args.getString(0);

                payPadManager = new PayPadManager(context, callbackContext);

                // showToast("About calling connecting");

                if(!BluetoothAdapter.getDefaultAdapter().isEnabled()){
                    try{
                        JSONObject jObject = new JSONObject();
                        jObject.put("operation","connection");
                        jObject.put("status","enabling_bluetooth");
                        r.setKeepCallback(true);
                       callbackContext.sendPluginResult(r);
                    }catch(JSONException e){

                    }

                    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    cordova.getActivity().startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT_M);

                }else{
                    doConnection(tempAddress,address);
                }
                
                // callbackContext.success(Globals.srn);

            } catch (Exception e){
                // callbackContext.error("Failed to parse parameters "+e.getMessage());
                callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, ""+e.getMessage()));
            }
            return true;

        }else if(action.equals("payment")){
            try {

                PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
                r.setKeepCallback(true);
                callbackContext.sendPluginResult(r);

                Context context = this.cordova.getActivity();
                payPadManager = new PayPadManager(context,callbackContext);



                String amount = args.getString(0);
                String accountType = args.getString(1);

                Globals.AccountTypeFromString = accountType;

                ReferenceList.config = context.getSharedPreferences(
                    Globals.preference, 0);
                Globals.merchantTerminalID = ReferenceList.config.getString(Globals.terminalIdKey,"");
                Globals.acceptorID = ReferenceList.config.getString(Globals.acceptorIDKey, "none");
                Globals.acceptorName = ReferenceList.config.getString(Globals.acceptorNameKey, "none");
                Globals.stan = Long.parseLong(ReferenceList.config.getString(Globals.stanKey, ""+Globals.stan));
                Globals.rrn = Long.parseLong(ReferenceList.config.getString(Globals.rrnKey, ""+Globals.rrn));

                String myx = ReferenceList.config.getString(Globals.terminalIdVasKey, "empty");

                //showToast("TID "+myx);

                if(accountType != null){

                    if(accountType.equalsIgnoreCase("current")) {
                        Globals.AccountTypeFrom = "20";                    
                    }else if(accountType.equalsIgnoreCase("credit")) {
                         Globals.AccountTypeFrom = "30";
                    }else{
                            // The default is saving
                        Globals.AccountTypeFrom = "10";
                    }

                }

                // showToast(amount + " : "+accountType);

                if(amount == null || amount.equals("0")){
                    // showToast("Invalid amount");
                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, "Invalid amount specified"));
                }else{
                    ReferenceList.config = context.getSharedPreferences(
                    Globals.preference, 0);

                    Thread th = new Thread(new Runnable() {

                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            try{

                                DecimalFormat format = new DecimalFormat("0.00");
                                ReferenceList.amount =  format.format(Double.parseDouble(arrays.getString(0)));
                                
                                payPadManager.makepayment(ReferenceList.amount);
                            }catch(Exception e){
                                String x = "";

                                for(StackTraceElement element : e.getStackTrace()){
                                    x += ""+element.toString();
                                }
                                PaypadFacade.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, ""+x));
                           }
                        }

                    });
                    th.start();
                }

                return true;

            } catch (Exception e){
                // callbackContext.error("Failed to parse parameters "+e.getMessage());
                String x = "";

                for(StackTraceElement element : e.getStackTrace()){
                    x += ""+element.toString();
                }
                callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, ""+x));
            }
        }else if(action.equals("vas")){
            try {

                PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
                r.setKeepCallback(true);
                callbackContext.sendPluginResult(r);

                Context context = this.cordova.getActivity();
                payPadManager = new PayPadManager(context,callbackContext);

                String amount = args.getString(0);
                String accountType = args.getString(1);

                // showToast(args.toString());

                Globals.AccountTypeFromString = accountType;

                // showToast(accountType+" "+args.getString(0)+" "+args.getLong(2)+" "+args.getLong(3));

                ReferenceList.config = context.getSharedPreferences(
                    Globals.preference, 0);
                Globals.merchantTerminalIDVas = ReferenceList.config.getString(Globals.terminalIdVasKey,"none");

                // showToast(Globals.merchantTerminalIDVas);

                if(Globals.merchantTerminalIDVas.equals("none")){
                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, "Vas not configured"));
                    return true;
                }

                Globals.acceptorIDVas = ReferenceList.config.getString(Globals.acceptorIDVasKey, "none");
                Globals.acceptorNameVas = ReferenceList.config.getString(Globals.acceptorNameVasKey, "none");

                // if(args.getLong(2) == 0){
                try{
                    Globals.stanVas = args.getLong(2);
                }catch(Exception ex){
                    Globals.stanVas = 5;
                }

                try{
                    Globals.rrnVas = args.getLong(3);
                }catch(Exception ex){
                    Globals.rrnVas = 5;
                }

                // showToast(Globals.rrnVas + " : "+Globals.stanVas);
                // Globals.rrnVas = Long.parseLong(ReferenceList.config.getString(Globals.rrnKey, ""+Globals.rrn));
                // showToast("TID "+Globals.merchantTerminalID);

                if(accountType != null){

                    if(accountType.equalsIgnoreCase("current")) {
                        Globals.AccountTypeFrom = "20";                    
                    }else if(accountType.equalsIgnoreCase("credit")) {
                         Globals.AccountTypeFrom = "30";
                    }else{
                            // The default is saving
                        Globals.AccountTypeFrom = "10";
                    }

                }

                // showToast(amount + " : "+accountType);

                if(amount == null || amount.equals("0")){
                    // showToast("Invalid amount");
                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, "Invalid amount specified"));
                }else{
                    ReferenceList.config = context.getSharedPreferences(
                    Globals.preference, 0);

                    Thread th = new Thread(new Runnable() {

                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            try{

                                DecimalFormat format = new DecimalFormat("0.00");
                                ReferenceList.amount =  format.format(Double.parseDouble(arrays.getString(0)));
                                
                                payPadManager.makepaymentvas(ReferenceList.amount);

                            }catch(Exception e){
                                String x = "";

                                for(StackTraceElement element : e.getStackTrace()){
                                    x += ""+element.toString();
                                }
                                PaypadFacade.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, ""+x));
                           }
                        }

                    });
                    th.start();
                }

            } catch (Exception e){
                // callbackContext.error("Failed to parse parameters "+e.getMessage());
                String x = "";

                for(StackTraceElement element : e.getStackTrace()){
                    x += ""+element.toString();
                }
                callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, ""+x));
            }

            return true;

        }else if (action.equals("vasreversal")){

            PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
            r.setKeepCallback(true);
            callbackContext.sendPluginResult(r);

            // This call to do a reversal on vas
            JSONObject jObject = new JSONObject();

            // showToast("Reversal called");

            try{
                jObject.put("operation","reversal");
                jObject.put("status","processing");
            }catch(JSONException ex){
            }

            r = new PluginResult(PluginResult.Status.OK, jObject);
            r.setKeepCallback(true);
            callbackContext.sendPluginResult(r);

            Context context = this.cordova.getActivity();
            payPadManager = new PayPadManager(context,callbackContext);

            Thread th = new Thread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    try{

                        EmvReversalProcessor emvReversalProcessor = new EmvReversalProcessor();
                        emvReversalProcessor.doReversal();

                    }catch(Exception e){
                        String x = "";

                        for(StackTraceElement element : e.getStackTrace()){
                            x += ""+element.toString();
                        }
                        PaypadFacade.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, ""+x));
                   }
                }

            });

            th.start();

            return true;

        }else if(action.equals("network")){
            
            boolean state = false;

            // showToast("checking network connection");

            Context context = this.cordova.getActivity();
            ConnectivityManager conMan = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

            if ( conMan.getNetworkInfo(0).getState() == NetworkInfo.State.CONNECTED) {

                state = true;
            }

            NetworkInfo networkInfo = conMan.getNetworkInfo(ConnectivityManager.TYPE_WIFI);

            if(networkInfo.isConnected()){
                state = true;
            }

            try{
                JSONObject jObject = new JSONObject();
                jObject.put("operation","network");
                jObject.put("status",""+state);
                callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, jObject));
                
            }catch(JSONException e){
                callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, "Unable to check for connection"));
            }

            return true;
        }else if(action.equalsIgnoreCase("startscan")){

            PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
            r.setKeepCallback(true);
            callbackContext.sendPluginResult(r);

            if(Globals.isPinpadConnected == false){
                callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, "Device not connected"));
                return true;
            }

            cordova.getThreadPool().execute(new Runnable() {
                public void run() {
                    try{                        
                        payPadManager.startScanning();
                    }catch(Exception ex){
                        callbackContext2.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, "Barcode: "+ex.getMessage()));
                    }
                }
            });

            return true;

        }else if(action.equalsIgnoreCase("stopscan")){

            PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
            r.setKeepCallback(true);
            callbackContext.sendPluginResult(r);

            if(Globals.isPinpadConnected == false){
                callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, "Device not connected"));
                return true;
            }

            cordova.getThreadPool().execute(new Runnable() {
                public void run() {
                    try{                        
                        payPadManager.stopScanning();
                    }catch(Exception ex){
                        callbackContext2.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, "Barcode: "+ex.getMessage()));
                    }
                }
            });

            return true;

        }else if(action.equals("enablebt")){
            
            PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
            r.setKeepCallback(true);
            callbackContext.sendPluginResult(r);

            // This is called to enable bluetooth
            if(!BluetoothAdapter.getDefaultAdapter().isEnabled()){
                try{
                    JSONObject jObject = new JSONObject();
                    jObject.put("operation","enablebt");
                    jObject.put("status","enabling_bluetooth");
                    r = new PluginResult(PluginResult.Status.OK, jObject);
                    r.setKeepCallback(true);
                   callbackContext.sendPluginResult(r);
                }catch(JSONException e){

                }

                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                cordova.getActivity().startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT_M_PRINTER);

            }else{
                
                try{
                    JSONObject jObject = new JSONObject();
                    jObject.put("operation","enablebt");
                    jObject.put("status","success");
                    r = new PluginResult(PluginResult.Status.OK, jObject);
                    r.setKeepCallback(false);
                    callbackContext.sendPluginResult(r);
                }catch(Exception ex){

                }
            }

            return true;
        }else if(action.equals("connectprinter")){

            // This gets the printer address from the message

            PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
            r.setKeepCallback(true);
            callbackContext.sendPluginResult(r);

            printerAddress = args.getString(0);

            // showToast("connectprinter");

            Context context = this.cordova.getActivity();
            ReferenceList.config = context.getSharedPreferences(
                Globals.preference, 0);
            lastKnowPrinter = ReferenceList.config.getString(Globals.printerAddressKey,"");

            if(BluetoothService.isPrinterConnected()){

                // showToast("Already connect");

                try{
                    JSONObject jObject = new JSONObject();
                    jObject.put("operation","connectprinter");
                    jObject.put("status","already_connected");
                    r = new PluginResult(PluginResult.Status.OK, jObject);
                    r.setKeepCallback(false);
                    callbackContext.sendPluginResult(r);
                }catch(JSONException ex){

                }

                return true;
            }

            // printerAddress = args.getString(0);

            // showToast("connectprinter");

            // Context context = this.cordova.getActivity();
            // ReferenceList.config = context.getSharedPreferences(
            //     Globals.preference, 0);
            // lastKnowPrinter = ReferenceList.config.getString(Globals.printerAddressKey,"");   

            // This is called to enable bluetooth
            if(!BluetoothAdapter.getDefaultAdapter().isEnabled()){
                try{
                    JSONObject jObject = new JSONObject();
                    jObject.put("operation","connectprinter");
                    jObject.put("status","enabling_bluetooth");
                    r = new PluginResult(PluginResult.Status.OK, jObject);
                    r.setKeepCallback(true);
                   callbackContext.sendPluginResult(r);
                }catch(JSONException e){

                }

                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                cordova.getActivity().startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT_M_PRINTER);

            }else{
                doPrinterConnection(printerAddress,lastKnowPrinter);
            }

            return true;

        }else if(action.equals("print")){

            PluginResult r;

            // showToast("in printing method");

            if(mService == null){

                try{
                    JSONObject jObject = new JSONObject();
                    jObject.put("operation","printing");
                    jObject.put("status","cannot_print");
                    r = new PluginResult(PluginResult.Status.OK, jObject);
                    r.setKeepCallback(false);
                    callbackContext2.sendPluginResult(r);

                }catch(Exception ex){
                    callbackContext2.sendPluginResult(new PluginResult(PluginResult.Status.ERROR,"printing Error : "+ex.getMessage()));
                }
            }else{

                try{

                    String header = args.getString(0); // This gets the header message
                    String footer = args.getString(2); // This gets the footer message
                    String poweredby = args.getString(3); 

                    // showToast(header);
                    // showToast(footer);
                    // showToast(poweredby);

                    

                    JSONObject jsonObject = args.getJSONObject(1); // This gets the body as a JSONObject

                    // showToast(jsonObject.toString());

                    Iterator<String> allKeys = jsonObject.keys();

                    Map<String,String> body = new HashMap();

                    while (allKeys.hasNext()) {

                        String key = (String) allKeys.next();
                        String value = jsonObject.getString(key);

                        body.put(key,value);
                    }

                    PrintModel printModel = new PrintModel();
                    printModel.setHeader(header);

                    List<String> subHeaders = new ArrayList<String>();
                    subHeaders.add("RECEIPT");

                    printModel.setSubHeader(subHeaders);
                    printModel.setPoweredBy(poweredby);
                    printModel.setFooter(footer);

                    printModel.setBody(body);

                    try{
                        JSONObject jObject = new JSONObject();
                        jObject.put("operation","printing");
                        jObject.put("status","printing");
                        r = new PluginResult(PluginResult.Status.OK, jObject);
                        r.setKeepCallback(true);
                        callbackContext2.sendPluginResult(r);

                    }catch(Exception ex){
                        callbackContext2.sendPluginResult(new PluginResult(PluginResult.Status.ERROR,"printing Error : "+ex.getMessage()));
                    }

                    mService.print(printModel);

                }catch(Exception ex){

                }

            }

            return true;

        }else if(action.equals("sms")){
            // This is the section where sms will be implemented

            PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
            r.setKeepCallback(true);
            callbackContext.sendPluginResult(r);

            String header = "RECEIPT";

            try {

                JSONObject jObject = new JSONObject();
                jObject.put("operation","sms");
                jObject.put("status","sending_sms");

                r = new PluginResult(PluginResult.Status.OK, jObject);
                r.setKeepCallback(true);
                callbackContext2.sendPluginResult(r);

                // PendingIntent sentPI = PendingIntent.getBroadcast(cordova.getActivity(),0,new Intent("SMS_SENT"),0);
                // cordova.getActivity().registerReceiver(new BroadcastReceiver() {
                //     @Override
                //     public void onReceive(Context context, Intent intent) {

                //         PluginResult r;

                //         try{
                        
                //             JSONObject jObject = new JSONObject();
                //             jObject.put("operation","sms");

                //             switch (getResultCode()){
                //                 case Activity.RESULT_OK:
                //                     jObject.put("status","sent");
                //                     break;
                //                 case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                //                     jObject.put("status","not_sending");
                //                     break;
                //                 case SmsManager.RESULT_ERROR_NO_SERVICE:
                //                     // Toast.makeText(getBaseContext(), "No service",
                //                     //         Toast.LENGTH_SHORT).show();
                //                     jObject.put("status","error_not_sending");
                //                     break;
                //                 case SmsManager.RESULT_ERROR_NULL_PDU:
                //                     // Toast.makeText(getBaseContext(), "Null PDU",
                //                     //         Toast.LENGTH_SHORT).show();
                //                     jObject.put("status","error_not_sending");
                //                     break;
                //                 case SmsManager.RESULT_ERROR_RADIO_OFF:
                //                     jObject.put("status","radio_off");
                //                     break;
                //             }

                //             r = new PluginResult(PluginResult.Status.OK, jObject);
                //         // r.setKeepCallback(true);
                //             callbackContext2.sendPluginResult(r);

                //         }catch(JSONException ex){

                //             r = new PluginResult(PluginResult.Status.ERROR, "Error: "+ex.getMessage());
                //             // r.setKeepCallback(true);
                //             callbackContext2.sendPluginResult(r);
                //         }

                        
                //     }
                // },new IntentFilter("SMS_SENT"));

                // [params.merchant,params.id,params.date,params.terminal,params.status,params.phone,params.amount]

                final SmsManager smsManager = SmsManager.getDefault();

                String receiptMsg = ""+header+"\r\n";
                receiptMsg += ""+args.getString(4)+"\r\n"; // This specifies if card transaction is approved or not
                receiptMsg += ""+args.getString(0)+"\r\n"; // This is the merchant Name
                receiptMsg += "Id: "+args.getString(1)+"\r\n"; // This is the transaction id
                receiptMsg += "Date: "+args.getString(2)+"\r\n"; // This is the date and time of transaction
                receiptMsg += "Terminal: "+args.getString(3)+"\r\n"; // This is the terminal Id
                receiptMsg += "Amnt: "+args.getString(6)+" NGN\r\n";
                receiptMsg += "Powered by Paypad";

                final String msg = receiptMsg;

                final String phoneN = args.getString(5);

                // showStaticToastLong("Message to send "+receiptMsg+" : "+args.getString(5));

                new Handler().post(new Runnable() {
                    @Override
                    public void run() {

                        ArrayList<String> msgN = smsManager.divideMessage(msg);
                        smsManager.sendMultipartTextMessage(phoneN,null,msgN,null, null);
        //                smsManager.
                        // startActivity(new Intent(Splashscreen.this,Signup.class));
                        // finish();
                    }
                });

                

                // smsManager.sendTextMessage(args.getString(5), null, receiptMsg, null, null);

                // showStaticToastLong("Message Sent "+receiptMsg);

                // jObject = new JSONObject();
                // jObject.put("operation","sms");
                // jObject.put("status","done");
                // r = new PluginResult(PluginResult.Status.OK, jObject);
                // r.setKeepCallback(false);
                // callbackContext2.sendPluginResult(r);

            }catch(Exception ex){

                showToast("Error "+ex.getMessage());
            }

            return true;

        }else if(action.equals("help")){
            try {

                // This ensure that the application waits for the result
                PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
                r.setKeepCallback(true);
                callbackContext.sendPluginResult(r);

                Context context = this.cordova.getActivity();

                try{
                    JSONObject jObject = new JSONObject();
                    jObject.put("operation","messaging");
                    jObject.put("status","sending");
                    r = new PluginResult(PluginResult.Status.OK, jObject);
                    r.setKeepCallback(true);
                    callbackContext.sendPluginResult(r);
                }catch(JSONException e){
                }

                String email = args.getString(0);
                String name = args.getString(1);
                String body = args.getString(2);

                Mail mail = new Mail("hello@paypad.com.ng", "resources");

                mail.setTo(new String[]{ "hello@paypad.com.ng", "oduwole@cashenvoy.com" }); // load array to setTo function
                mail.setFrom(email); 
                mail.setSubject("Paypad Help from "+name);
                // showToast(body);

                mail.setBody(body);

                if (mail.send()) {
                // success
                JSONObject jObject = new JSONObject();
                jObject.put("operation","messaging");
                jObject.put("status","sent");
                r = new PluginResult(PluginResult.Status.OK, jObject);
                r.setKeepCallback(false);
                callbackContext.sendPluginResult(r);
                // showToast("Email send successfully");

                } else {
                    // failure
                    //showToast("Email not send successfully");
                    JSONObject jObject = new JSONObject();
                    jObject.put("operation","messaging");
                    jObject.put("status","failed");
                    r = new PluginResult(PluginResult.Status.ERROR, jObject);
                    r.setKeepCallback(false);
                    callbackContext.sendPluginResult(r);
                }

                // callbackContext.success(Globals.srn);

            } catch (Exception e){
                // callbackContext.error("Failed to parse parameters "+e.getMessage());
                String x = "";
            
                for(StackTraceElement element : e.getStackTrace()){
                    x += element.toString();
                }

                callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, ""+e.getMessage()));
            }
            return true;
        }else if(action.equals("battery")){

            cordova.getThreadPool().execute(new Runnable() {
                public void run() {
                    try{

                        JSONObject batteryStats = payPadManager.getBatteryStats();
                        // callbackContext2.sendPluginResult(new PluginResult(PluginResult.Status.OK, batteryStats));

                        callbackContext2.success(batteryStats);

                    }catch(Exception ex){
                        callbackContext2.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, "Battery: "+ex.getMessage()));
                    }
                }
            });

            return true;
        }

        return false;
    }

    @Override
    public void initialize(CordovaInterface cordova, CordovaWebView webView) {

        // This sets the callback to this class
        cordova.setActivityResultCallback(this);

        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);

        webView.getContext().registerReceiver(mStateReceiver, filter);
        // webView.getContext().registerReceiver(this.receiver, intentFilter);

        // This allows for the binding of bluetoothservice to the connection class;
        Intent intent = new Intent(cordova.getActivity(), BluetoothService.class);
        webView.getContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

        super.initialize(cordova,webView);
    }

    @Override
    public void onDestroy() {
        if (mStateReceiver != null) {
            try {

                BluetoothService.closePinter();

                webView.getContext().unregisterReceiver(mStateReceiver);

            } catch (Exception e) {
                // Log.e(LOG_TAG, "Error unregistering network receiver: " + e.getMessage(), e);
                System.out.println("Error : "+e.getMessage());
            } finally {
                mStateReceiver = null;
            }
        }
    }

    // @Override
    // public void setActivityResultCallback(CordovaPlugin plugin) {
    //     this.activityResultCallback = plugin;        
    // }

    // public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) {
    //     this.activityResultCallback = command;
    //     // this.activityResultKeepRunning = this.keepRunning;

    //     // If multitasking turned on, then disable it for activities that return results
    //     // if (command != null) {
    //     //     this.keepRunning = false;
    //     // }

    //     // Start activity
    //     super.startActivityForResult(intent, requestCode);
    // }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent){

        // showToast("Rece "+requestCode+" : "+PayPadManager.REQUEST_ENABLE_BT);
        if(requestCode == PayPadManager.REQUEST_ENABLE_BT || requestCode == PayPadManager.REQUEST_DEVICE){
            payPadManager.onActivityResult(requestCode,resultCode,intent);
            // callbackContext.success(Globals.srn+"hello");

            // showToast(" My callback is working "+Globals.srn);
        }else if(requestCode == REQUEST_ENABLE_BT_M){
            doConnection(tempAddress,address);

            // showToast("bluetooth enabled");
        }else if (requestCode == REQUEST_ENABLE_BT_M_PRINTER){

            try{

                // JSONObject jObject = new JSONObject();
                // jObject.put("operation","enablebt");
                // jObject.put("status","success");
                // PluginResult r = new PluginResult(PluginResult.Status.OK, jObject);
                // r.setKeepCallback(false);
                // callbackContext.sendPluginResult(r);

                doPrinterConnection(printerAddress,lastKnowPrinter);

            }catch(Exception ex){

            }

        }
        // super.onActivityResult(requestCode, resultCode, intent);

        // CordovaPlugin callback = this.activityResultCallback;
        //     if (callback != null) {
        //         callback.onActivityResult(requestCode, resultCode, intent);
        // }
    }


    public void doConnection(String temp,String address){

        try{
            PluginResult r = null;

            // showToast("do fion");
            if(Globals.isPinpadConnected == true){
                try{
                    JSONObject jObject = new JSONObject();
                    jObject.put("operation","connection");
                    jObject.put("status","already_connected");
                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, jObject));
                }catch(JSONException e){

                }
            }
            else if(temp.equals("") && !address.equals("")){

                //showToast("do connection both");

                 try{
                    JSONObject jObject = new JSONObject();
                    jObject.put("operation","connection");
                    jObject.put("status","connecting");
                    r = new PluginResult(PluginResult.Status.OK, jObject);
                    r.setKeepCallback(true);
                    callbackContext.sendPluginResult(r);

                }catch(JSONException e){
                }

                // showToast("About calling connecting");

                payPadManager.connect(address);

            }else if(!temp.equals("")){

                //showToast("do connection temp only");
                try{
                    JSONObject jObject = new JSONObject();
                    jObject.put("operation","connection");
                    jObject.put("status","connecting");
                    r = new PluginResult(PluginResult.Status.OK, jObject);
                    r.setKeepCallback(true);
                    callbackContext.sendPluginResult(r);

                }catch(JSONException e){

                }

                payPadManager.connect(temp);

            }else{
                
                try{
                    JSONObject jObject = new JSONObject();
                    jObject.put("operation","connection");
                    jObject.put("status","not_connected");
                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, jObject));
                }catch(JSONException e){
                }

            }
        }catch(Exception ex){
            try{

                JSONObject jObject = new JSONObject();
                jObject.put("operation","connection");
                jObject.put("status","error: "+ ex.getMessage());
                callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, jObject));

            }catch(JSONException e){
            }
        }

    }


    public void doPrinterConnection(String address, String lastKnowPrinter){


        // showToast("in do printer");

        if(address.equals("") && lastKnowPrinter.equals("")){

            // showToast("No available printer");

            try{
                JSONObject jObject = new JSONObject();
                jObject.put("operation","connectprinter");
                jObject.put("status","no_selected_printer");
                 PluginResult r = new PluginResult(PluginResult.Status.OK, jObject);
                r.setKeepCallback(false);
                callbackContext.sendPluginResult(r);
            }catch(JSONException ex){
                // showToast("Error in no available "+ex.getMessage());
            }

        }else if(address.equals("") && !lastKnowPrinter.equals("")){

            // enter here if no address is provided but there is a lastknown device
            // PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
            // r.setKeepCallback(true);
            // callbackContext.sendPluginResult(r);

            // showToast("available previous printer");

            try{
                JSONObject jObject = new JSONObject();
                jObject.put("operation","connectprinter");
                jObject.put("status","connecting");
                PluginResult r = new PluginResult(PluginResult.Status.OK, jObject);
                r.setKeepCallback(true);
                callbackContext.sendPluginResult(r);

                Intent intent = new Intent(cordova.getActivity(), BluetoothService.class);
                intent.putExtra(DEVICE_ADDRESS, lastKnowPrinter);
                cordova.getActivity().startService(intent);
            }catch(Exception ex){

            }

        }else{

            // enter here if address is provided 

            // showToast("connecting to new printer");

            try{
                JSONObject jObject = new JSONObject();
                jObject.put("operation","connectprinter");
                jObject.put("status","connecting");
                PluginResult r = new PluginResult(PluginResult.Status.OK, jObject);
                r.setKeepCallback(true);
                callbackContext.sendPluginResult(r);

                Intent intent = new Intent(cordova.getActivity(), BluetoothService.class);
                intent.putExtra(DEVICE_ADDRESS, address);
                cordova.getActivity().startService(intent);
            }catch(Exception ex){

            }
        }
    }

    // @Override
    // public void onResume(boolean multitasking) {
    //     // super.onResume(multitasking);
    //     this.cordova.getActivity().registerReceiver(mReceiver, filter1);
    //     this.cordova.getActivity().registerReceiver(mReceiver, filter2);
    //     this.cordova.getActivity().registerReceiver(mReceiver, filter3);
    // }

    // // @Override
    // // protected void onResume() {
    // //     super.onResume();
    // //     this.registerReceiver(mReceiver, filter1);
    // //     this.registerReceiver(mReceiver, filter2);
    // //     this.registerReceiver(mReceiver, filter3);
    // // }

    // @Override
    // public void onPause(boolean multitasking) {
    //     // super.onPause(multitasking);
    //     this.cordova.getActivity().unregisterReceiver(mReceiver);
    // }

    private void showToast(final String text) {
        this.cordova.getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(activity, text,
                        Toast.LENGTH_SHORT).show();
            }
        });
    }

    public static void showStaticToast(final String text){
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(activity, text,
                        Toast.LENGTH_SHORT).show();
            }
        });
    }

    public static void showStaticToastLong(final String text){
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(activity, text,
                        Toast.LENGTH_LONG).show();
            }
        });
    }

}
