package com.qianmi.lkl;


import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.util.Printer;
import android.view.View;

import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.BaseActivityEventListener;
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.lkl.cloudpos.aidl.AidlDeviceService;
import com.lkl.cloudpos.aidl.printer.AidlPrinter;
import com.lkl.cloudpos.aidl.printer.AidlPrinterListener;
import com.lkl.cloudpos.aidl.printer.PrintItemObj;
import com.lkl.cloudpos.data.AidlErrorCode;
import com.newland.jsums.paylib.model.NLResult;
import com.newland.jsums.paylib.model.OrderInfo;

import java.util.ArrayList;
import java.util.List;


/**
 * Created by tzz on 2017/8/18.
 */

public class LklModule extends ReactContextBaseJavaModule {

    private static final String LKL_RESULT_CODE = "LKL_RESULT_CODE";
    private static final int requestCode = 5000;
    private static String TAG  = "LKL_MODULE"; //打印日志TAG
    public static final String LKL_SERVICE_ACTION = "lkl_cloudpos_mid_service"; //行业应用服务名

    private AidlPrinter printerDev = null;

    //设别服务连接桥
    private ServiceConnection conn = new ServiceConnection(){
        @Override
        public void onServiceConnected(ComponentName name, IBinder serviceBinder) {
            Log.d(TAG,"行业SDK服务连接成功");
            if(serviceBinder != null){
                //获取设备服务实例
                AidlDeviceService serviceManager = AidlDeviceService.Stub.asInterface(serviceBinder);
                onDeviceConnected(serviceManager);
            }
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG,"行业SDK服务断开了");
        }
    };

    /**
     * 绑定服务
     */
    public void bindService(){
        try{
            Intent intent = new Intent();
            intent.setAction(LKL_SERVICE_ACTION);
            Intent eintent = new Intent(getExplicitIntent(getReactApplicationContext(), intent));
            boolean flag = false;
            flag = getReactApplicationContext().bindService(eintent, conn, Context.BIND_AUTO_CREATE);
            if(flag){
                Log.d(TAG,"----------服务绑定成功------");
            }else{
                Log.d(TAG,"----------服务绑定失败-------");
            }
        } catch (Exception e) {
            return;
        }
    }

    /**
     * 获取启动服务的Intent
     * @param context
     * @param implicitIntent
     * @return
     */
    public static Intent getExplicitIntent(Context context, Intent implicitIntent) {
        //根据intent信息，获取相匹配的服务
        PackageManager pm = context.getPackageManager();
        List<ResolveInfo> resolveInfos = pm.queryIntentServices(implicitIntent, 0);
        //保证服务的唯一性
        if (resolveInfos == null || resolveInfos.size() != 1) {
            return null;
        }
        //获取组件信息，创建组件名
        ResolveInfo serviceInfo = resolveInfos.get(0);
        Log.d("PackageName",resolveInfos.size() + "");
        String packageName = serviceInfo.serviceInfo.packageName;
        String className = serviceInfo.serviceInfo.name;
        ComponentName component = new ComponentName(packageName, className);
        Intent explicitIntent = new Intent(implicitIntent);
        explicitIntent.setComponent(component);
        return explicitIntent;
    }

    public void onDeviceConnected(AidlDeviceService serviceManager) {
        try {
            printerDev = AidlPrinter.Stub.asInterface(serviceManager.getPrinter());
            //showMessage("绑定打印服务成功");
            Log.d(TAG,"绑定打印服务成功");
        } catch (RemoteException e) {
            e.printStackTrace();
            //showMessage("绑定打印服务失败");
            Log.d(TAG,"绑定打印服务失败");
        }
    }

    LklModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @ReactMethod
    public void create(){
        Log.i("------create-----","------------>>>");
        getReactApplicationContext().addActivityEventListener(mActivityEventListener);
        bindService();
    }

    @ReactMethod
    public void startActivityForResult(String money,String tid,String time){
        Log.i("startActivityForResult","------------>>>>money:"+money+" tid:"+tid+" time:"+time);

        try {
            ComponentName component = new ComponentName("com.lkl.cloudpos.payment", "com.lkl.cloudpos.payment.activity.MainMenuActivity");
            Intent intent = new Intent();
            intent.setComponent(component);

            Bundle bundle = new Bundle();
            bundle.putString("msg_tp",  "0200");
            bundle.putString("pay_tp",  "0");
            bundle.putString("proc_tp",  "00");
            bundle.putString("proc_cd", "000000");
            bundle.putString("amt",     money);
            bundle.putString("order_no",     tid);
            bundle.putString("appid",     "com.lkl.cloudpos.collect");
            bundle.putString("time_stamp", time);
            bundle.putString("order_info", "订单商品明细单价等xxxxxx");
            intent.putExtras(bundle);
            getReactApplicationContext().startActivityForResult(intent, 1,bundle);
        } catch(ActivityNotFoundException e) {
            Log.d("eee0",e.getMessage());
            LklModule.this.getReactApplicationContext()
                    .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(LKL_RESULT_CODE, "跳转页面异常"+" 目标页面不存在");


        } catch(Exception e) {
            Log.d("eee1",e.getMessage());
            LklModule.this.getReactApplicationContext()
                    .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(LKL_RESULT_CODE, "跳转页面异常"+e.getMessage());
        }
    }

    @ReactMethod
    public void printReceipt(){
        Log.i("--printReceipt-"," aidlPrinter: = null "+(printerDev == null));
        getPrintState();
        //printText();

        printEmptyLine();
        printEmptyLine();
        printShopName("千米线下体验店");
        printEmptyLine();
        printEmptyLine();
        printLineWrap("单号：TCC20171818181112221212221889",true);
        printLineWrap("时间：2017008-12 11：33：44",true);
        printLineWrap("支付方式：现金",true);
        printEmptyLine();
        printEmptyLine();
        printDashLine();
        printColumnName();
        printColumnData("拉卡拉测试商品A001","2","2","4");
        printColumnData("拉卡拉测试商品A002","20","2.2","44.4");
        printColumnData("拉卡拉测试商品A002","19","1.89","35.91");
        printColumnData("拉卡拉测试商品A003","200","22.2","44440");
        printColumnData("拉卡拉测试商品A004","2000.00","22.2","44400.44");
        printEmptyLine();
        printDashLine();
        printHalfColumnData("数量：4","总额：2000.00");
        printEmptyLine();
        printHalfColumnData("实收：45.32","优惠金额：200.02");
        printEmptyLine();
        printLineWrap("找零：22.32",true);
        printDashLine();
        printLineWrap("会员卡号：-----",true);
        printLineWrap("积分余额：-----",true);
        printEmptyLine();
        printEmptyLine();

    }

    @ReactMethod
    public void printText(){
        try {
            final PrintItemObj obj = new PrintItemObj("测试企业",20,true, PrintItemObj.ALIGN.CENTER,false,false,40,5);
            printerDev.printText(new ArrayList<PrintItemObj>(){
                {
                    Log.d("PRINT","位图开始打印");
                    //请参考开发文档，定义打印字体对象PrintItemObj相关属性
                    add(new PrintItemObj("默认打印数据测试"));
//					add(new PrintItemObj("默认打印数据测试"));
//					add(new PrintItemObj("默认打印数据测试"));
//					add(new PrintItemObj("打印数据字体放大",24));
//					add(new PrintItemObj("打印数据字体放大",24));
//					add(new PrintItemObj("打印数据字体放大",24));
//					add(new PrintItemObj("打印数据加粗",8,true));
//					add(new PrintItemObj("打印数据加粗",8,true));
//					add(new PrintItemObj("打印数据加粗",8,true));
//					add(new PrintItemObj("打印数据左对齐测试",8,false,ALIGN.LEFT));
//					add(new PrintItemObj("打印数据左对齐测试",8,false,ALIGN.LEFT));
//					add(new PrintItemObj("打印数据左对齐测试",8,false,ALIGN.LEFT));
//					add(new PrintItemObj("打印数据居中对齐测试",8,false,ALIGN.CENTER));
//					add(new PrintItemObj("打印数据居中对齐测试",8,false,ALIGN.CENTER));
//					add(new PrintItemObj("打印数据居中对齐测试",8,false,ALIGN.CENTER));
//					add(new PrintItemObj("打印数据右对齐测试",8,false,ALIGN.RIGHT));
//					add(new PrintItemObj("打印数据右对齐测试",8,false,ALIGN.RIGHT));
//					add(new PrintItemObj("打印数据右对齐测试",8,false,ALIGN.RIGHT));
					add(new PrintItemObj("打印数据下划线",8,false, PrintItemObj.ALIGN.LEFT,true));
					add(new PrintItemObj("打印数据下划线",8,false, PrintItemObj.ALIGN.LEFT,true));
					add(new PrintItemObj("打印数据下划线",8,false, PrintItemObj.ALIGN.LEFT,true));
                  add(new PrintItemObj("打印数据不换行测试打印数据不换行测试打印数据不换行测试",8,false, PrintItemObj.ALIGN.LEFT,false,true));
                  add(new PrintItemObj("打印数据不换行测试打印数据不换行测试打印数据不换行测试",8,false, PrintItemObj.ALIGN.LEFT,false,false));
					add(new PrintItemObj("打印数据不换行测试打印数据不换行测试打印数据不换行测试",8,false, PrintItemObj.ALIGN.LEFT,false,false));
//					add(new PrintItemObj("打印数据行间距测试",8,false, PrintItemObj.ALIGN.LEFT,false,true,40));
//					add(new PrintItemObj("打印数据行间距测试",8,false, PrintItemObj.ALIGN.LEFT,false,true,100));
//					add(new PrintItemObj("打印数据行间距测试",8,false, PrintItemObj.ALIGN.LEFT,false,true,40));
//					add(new PrintItemObj("打印数据字符间距测试",8,false, PrintItemObj.ALIGN.LEFT,false,true,29,25));
//					add(new PrintItemObj("打印数据字符间距测试",8,false, PrintItemObj.ALIGN.LEFT,false,true,29,25));
//					add(new PrintItemObj("打印数据字符间距测试",8,false, PrintItemObj.ALIGN.LEFT,false,true,29,25));
//					add(new PrintItemObj("打印数据左边距测试",8,false,ALIGN.LEFT,false,true,29,0,40));
//					add(new PrintItemObj("打印数据左边距测试",8,false, PrintItemObj.ALIGN.LEFT,false,true,100,0,40));
//					add(new PrintItemObj("打印数据左边距测试",8,false, PrintItemObj.ALIGN.LEFT,false,true,29,0,40));
                }
            }, new AidlPrinterListener.Stub() {
                @Override
                public void onPrintFinish() throws RemoteException {

                    Log.d(TAG,"打印完成");
                }
                @Override
                public void onError(int arg0) throws RemoteException {
                    Log.d(TAG,"打印出错，错误码为：" + arg0);
                }
            });
        } catch (RemoteException e) {
            e.printStackTrace();
            Log.d(TAG,"打印异常");
        }
    }

       /**
     * 打印空行
     */
    @ReactMethod
    public void printQrCode(String text) {
        final byte[] bytes = BytesUtil.getZXingQRCode(text, 330);
        try {
            printerDev.printText(new ArrayList<PrintItemObj>() {
                {
                    Log.d("printQrCode", "开始打印空行");
                    add(new PrintItemObj(new String(bytes, "GBK"), 4, false, PrintItemObj.ALIGN.CENTER, false));
                }
            }, new AidlPrinterListener.Stub() {
                @Override
                public void onPrintFinish() throws RemoteException {
                    Log.d(TAG, "打印完成");
                }

                @Override
                public void onError(int arg0) throws RemoteException {
                    Log.d(TAG, "打印出错，错误码为：" + arg0);
                }
            });
        } catch (RemoteException e) {
            e.printStackTrace();
            Log.d(TAG, "打印异常");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 打印空行
     */
     @ReactMethod
    public void printEmptyLine(){
        try {
            printerDev.printText(new ArrayList<PrintItemObj>(){
                {
                    Log.d("printEmptyLine","开始打印空行");
                    add(new PrintItemObj("",4,false, PrintItemObj.ALIGN.CENTER,false));
                }
            }, new AidlPrinterListener.Stub() {
                @Override
                public void onPrintFinish() throws RemoteException {
                    Log.d(TAG,"打印完成");
                }
                @Override
                public void onError(int arg0) throws RemoteException {
                    Log.d(TAG,"打印出错，错误码为：" + arg0);
                }
            });
        } catch (RemoteException e) {
            e.printStackTrace();
            Log.d(TAG,"打印异常");
        }
    }

    /**
     * 打印店铺名称
     * @param shopName
     */
     @ReactMethod
    public void printShopName(final String shopName){
        try {
            printerDev.printText(new ArrayList<PrintItemObj>(){
                {
                    Log.d("printShopName","位图开始打印");
                    add(new PrintItemObj(shopName,8*2,false, PrintItemObj.ALIGN.CENTER,false));
                }
            }, new AidlPrinterListener.Stub() {
                @Override
                public void onPrintFinish() throws RemoteException {
                    Log.d(TAG,"打印完成");
                }
                @Override
                public void onError(int arg0) throws RemoteException {
                    Log.d(TAG,"打印出错，错误码为：" + arg0);
                }
            });
        } catch (RemoteException e) {
            e.printStackTrace();
            Log.d(TAG,"打印异常");
        }
    }

    /**
     * 打印单行
     * @param text
     */
     @ReactMethod
    public void printLineWrap(final String text, final boolean isWarp){
        try {
            printerDev.printText(new ArrayList<PrintItemObj>(){
                {
                    Log.d("printLineWrap","位图开始打印");
                    add(new PrintItemObj(text,8,false, PrintItemObj.ALIGN.LEFT,false,isWarp));
                }
            }, new AidlPrinterListener.Stub() {
                @Override
                public void onPrintFinish() throws RemoteException {
                    Log.d(TAG,"打印完成");
                }
                @Override
                public void onError(int arg0) throws RemoteException {
                    Log.d(TAG,"打印出错，错误码为：" + arg0);
                }
            });
        } catch (RemoteException e) {
            e.printStackTrace();
            Log.d(TAG,"打印异常");
        }
    }

    /**
       * 打印单行
       * @param text
       */
       @ReactMethod
      public void printLineBottom(final String text){
          try {
              printerDev.printText(new ArrayList<PrintItemObj>(){
                  {
                      Log.d("printLineWrap","位图开始打印");
                      add(new PrintItemObj(text,8,false, PrintItemObj.ALIGN.CENTER,false));
                  }
              }, new AidlPrinterListener.Stub() {
                  @Override
                  public void onPrintFinish() throws RemoteException {
                      Log.d(TAG,"打印完成");
                  }
                  @Override
                  public void onError(int arg0) throws RemoteException {
                      Log.d(TAG,"打印出错，错误码为：" + arg0);
                  }
              });
          } catch (RemoteException e) {
              e.printStackTrace();
              Log.d(TAG,"打印异常");
          }
      }

    /**
     * 打印虚线
     */
     @ReactMethod
    public void printDashLine(){
        try {
            printerDev.printText(new ArrayList<PrintItemObj>(){
                {
                    Log.d("printDashLine","位图开始打印");
                    add(new PrintItemObj("---------------------------------",8,false, PrintItemObj.ALIGN.LEFT,false,false));
                }
            }, new AidlPrinterListener.Stub() {
                @Override
                public void onPrintFinish() throws RemoteException {
                    Log.d(TAG,"打印完成");
                }
                @Override
                public void onError(int arg0) throws RemoteException {
                    Log.d(TAG,"打印出错，错误码为：" + arg0);
                }
            });
        } catch (RemoteException e) {
            e.printStackTrace();
            Log.d(TAG,"打印异常");
        }
    }


    /**
     * 打印列名
     */
     @ReactMethod
    public void printColumnName(){
        try {
            printerDev.printText(new ArrayList<PrintItemObj>(){
                {
                    Log.d("printDashLine","位图开始打印");
                    add(new PrintItemObj("商品名称     单价  数量  小计  ",8,false, PrintItemObj.ALIGN.LEFT,false,true));
                }
            }, new AidlPrinterListener.Stub() {
                @Override
                public void onPrintFinish() throws RemoteException {
                    Log.d(TAG,"打印完成");
                }
                @Override
                public void onError(int arg0) throws RemoteException {
                    Log.d(TAG,"打印出错，错误码为：" + arg0);
                }
            });
        } catch (RemoteException e) {
            e.printStackTrace();
            Log.d(TAG,"打印异常");
        }
    }


    /**
     * 打印列数据
     */
     @ReactMethod
    public void printColumnData(String goodsName,String price,String count,String total){
        String lineData = "商品名称      单价   数量  小计";
        String column1 = "商品名称名称名";
        String column2 = "9999.99";
        String column3 = "99999.99";

        if(count.length() <= 4){
            column2 = "9999";
        }

        final String line = filterColumn(goodsName,column1) +" " + filterColumn(price,column2)+" " + filterColumn(count,column2)
                       +"" + filterColumn(total,column3);
        try {
            printerDev.printText(new ArrayList<PrintItemObj>(){
                {
                    Log.d("printDashLine","位图开始打印");
                    add(new PrintItemObj(line,8,false, PrintItemObj.ALIGN.LEFT,false,true));
                }
            }, new AidlPrinterListener.Stub() {
                @Override
                public void onPrintFinish() throws RemoteException {
                    Log.d(TAG,"打印完成");
                }
                @Override
                public void onError(int arg0) throws RemoteException {
                    Log.d(TAG,"打印出错，错误码为：" + arg0);
                }
            });
        } catch (RemoteException e) {
            e.printStackTrace();
            Log.d(TAG,"打印异常");
        }
    }

    /**
     * 打印列数据
     */
     @ReactMethod
    public void printHalfColumnData(String paramLeft,String paramRight){
        String lineData = "商品名称       单价   数量  小计";
         String column1 = "实收：99999。99";
         String column2 = "1234512345";


        final String line = filterColumn(paramLeft,column1) + filterColumn(paramRight,column2);

        try {
            printerDev.printText(new ArrayList<PrintItemObj>(){
                {
                    Log.d("printHalfColumnData","位图开始打印");
                    add(new PrintItemObj(line,8,false, PrintItemObj.ALIGN.LEFT,false,true));
                }
            }, new AidlPrinterListener.Stub() {
                @Override
                public void onPrintFinish() throws RemoteException {
                    Log.d(TAG,"打印完成");
                }
                @Override
                public void onError(int arg0) throws RemoteException {
                    Log.d(TAG,"打印出错，错误码为：" + arg0);
                }
            });
        } catch (RemoteException e) {
            e.printStackTrace();
            Log.d(TAG,"打印异常");
        }
    }


    private String filterColumn(String param,String format){
        if(param.length() > format.length()){
            return param.substring(0,format.length() - 1)+" ";
        }else{
            String emp = "           ";

            int len = format.length();
            int paramLen = param.length();
            Log.d(TAG,"len: "+len);
            Log.d(TAG,"paramLen: "+paramLen);
            String tmp = param + emp.substring(0,len - paramLen);
            return tmp+" ";
        }
    }


    /**
     * 获取打印机状态
     */
     @ReactMethod
    public void getPrintState(){
        try {
            int printState = printerDev.getPrinterState();
            Log.d(TAG,"获取到的打印机状态为" + printState);
        } catch (RemoteException e) {
            e.printStackTrace();
            Log.d(TAG,"获取到的打印机状态失败");
        }

    }

    @ReactMethod
    public void destroy(){
        getReactApplicationContext().removeActivityEventListener(mActivityEventListener);
        getReactApplicationContext().unbindService(conn);
    }

    private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() {

        @Override
        public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {

            super.onActivityResult(requestCode, resultCode, data);
            switch (resultCode) {
                // 支付成功
                case Activity.RESULT_OK:
                    LklModule.this.getReactApplicationContext()
                            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(LKL_RESULT_CODE, "交易成功");
                    break;
                // 支付取消
                case Activity.RESULT_CANCELED:
//                    Bundle bundle = data.getExtras();
//                    String reason = bundle.getString("reason");
//                    if (data != null && data.getExtras() !=null && data.getExtras().getString("reason") != null) {
                        LklModule.this.getReactApplicationContext()
                                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(LKL_RESULT_CODE, "交易取消");
//                    }
                    break;
                case -2:
                    //交易失败
                    Bundle bundle1 = data.getExtras();
                    String reason1 = bundle1.getString("reason");
                    if (reason1 != null) {
                        LklModule.this.getReactApplicationContext()
                                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(LKL_RESULT_CODE, reason1);
                    }
                    break;
                default:
                    LklModule.this.getReactApplicationContext()
                            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(LKL_RESULT_CODE, "交易失败");

                    break;
            }
        }
    };

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