package xbyps.xtgyl.cn.react_native_sunmi_printer;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Environment;
import android.util.Log;
import android.view.Display;

import com.facebook.react.bridge.Callback;
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.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.IOException;
import java.util.List;

import xbyps.xtgyl.cn.react_native_sunmi_printer.bean.TableItem;
import xbyps.xtgyl.cn.react_native_sunmi_printer.present.VideoDisplay;
import xbyps.xtgyl.cn.react_native_sunmi_printer.presentation.ScreenManager;
import xbyps.xtgyl.cn.react_native_sunmi_printer.receiver.MyBroadCastReceiver;
import xbyps.xtgyl.cn.react_native_sunmi_printer.utils.AidlUtil;
import xbyps.xtgyl.cn.react_native_sunmi_printer.utils.BluetoothUtil;
import xbyps.xtgyl.cn.react_native_sunmi_printer.utils.BytesUtil;
import xbyps.xtgyl.cn.react_native_sunmi_printer.utils.ESCUtil;

/**
 * Created by Administrator on 2019/01/18.
 */

public class SunMiPrinterModule extends ReactContextBaseJavaModule {
    private final String TAG = "SunMiPrinterModule";
    private final ReactApplicationContext myReactContext;
    private static final int QRCODE_SIZE = 350;
    private static final int BARCODE_WIDTH = 500;
    private static final int BARCODE_HEIGHT = 80;
    private int record;
    private float size;
    private boolean isBold, isUnderLine;
    private boolean isAidl = true;
    private String[] mStrings = new String[]{"CP437", "CP850", "CP860", "CP863", "CP865", "CP857", "CP737", "CP928", "Windows-1252", "CP866", "CP852", "CP858", "CP874", "Windows-775", "CP855", "CP862", "CP864", "GB18030", "BIG5", "KSC5601", "utf-8"};
    private Bitmap bitmap, bitmap1;
    private ScreenManager screenManager = ScreenManager.getInstance();
    private VideoDisplay videoDisplay = null;

    public SunMiPrinterModule(ReactApplicationContext reactContext) {
        super(reactContext);
        //给上下文对象赋值
        this.myReactContext = reactContext;
        record = 17;
        isBold = false;
        isUnderLine = false;
        size = Integer.parseInt("24");//打印机文字大小
        AidlUtil.getInstance().connectPrinterService(reactContext);
    }

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


    /**************************************************************************************
     *打印机相关方法总汇
     **************************************************************************************/

    /*
     * 初始化打印机
     */
    @ReactMethod
    public void initPrinter(Callback successCallback, Callback failCallback) {
        //初始化打印机
        AidlUtil.getInstance().initPrinter();
    }

    /*
     * 打印文字
     */
    @ReactMethod
    public void printText(String content, int size, Boolean isBold, Boolean isUnderLine, Callback successCallback, Callback failCallback) {
        if (isAidl) {
            AidlUtil.getInstance().printText(content, size, isBold, isUnderLine);
        } else {
            printByBluTooth(content);
        }
        // successCallback.invoke(true);
        // failCallback.invoke(e)；
    }

    /*
     * 切纸
     */
    @ReactMethod
    public void cutPaper(Callback successCallback, Callback failCallback) {
        AidlUtil.getInstance().cutPaper();

    }

    /*
     * 打印空行
     */
    @ReactMethod
    public void printLine(int line, Callback successCallback, Callback failCallback) {
        AidlUtil.getInstance().printLine(line);

    }

    /*
     * 打印图片
     */
    @ReactMethod
    public void printPicture(Callback successCallback, Callback failCallback) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inTargetDensity = 40;
        options.inDensity = 40;
        if (bitmap == null) {
            bitmap = BitmapFactory.decodeResource(this.myReactContext.getResources(), R.drawable.xbyz, options);
        }

        if (bitmap1 == null) {
            bitmap1 = BitmapFactory.decodeResource(this.myReactContext.getResources(), R.drawable.xbyz, options);
            bitmap1 = scaleImage(bitmap1);
        }

        if (isAidl) {
            AidlUtil.getInstance().printBitmapPicture(bitmap);
        } else {
            BluetoothUtil.sendData(ESCUtil.printBitmap(bitmap1, 0));
//            BluetoothUtil.sendData(ESCUtil.nextLine(3));
        }
    }

    /*
     * 打印文字图片
     */
    @ReactMethod
    public void printTextPicture(int orientation, String content, int size, Callback successCallback, Callback failCallback) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inTargetDensity = 40;
        options.inDensity = 40;
        if (bitmap == null) {
            bitmap = BitmapFactory.decodeResource(this.myReactContext.getResources(), R.drawable.xbyz, options);
        }

        if (bitmap1 == null) {
            bitmap1 = BitmapFactory.decodeResource(this.myReactContext.getResources(), R.drawable.xbyz, options);
            bitmap1 = scaleImage(bitmap1);
        }

        if (isAidl) {
            AidlUtil.getInstance().printBitmap(bitmap, orientation, content, size);
        } else {
            BluetoothUtil.sendData(ESCUtil.printBitmap(bitmap1, 0));
//            BluetoothUtil.sendData(ESCUtil.nextLine(3));
        }
    }

    private Bitmap scaleImage(Bitmap bitmap1) {
        int width = bitmap1.getWidth();
        int height = bitmap1.getHeight();
        // 设置想要的大小
        int newWidth = (width / 8 + 1) * 8;
        // 计算缩放比例
        float scaleWidth = ((float) newWidth) / width;
        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, 1);
        // 得到新的图片
        return Bitmap.createBitmap(bitmap1, 0, 0, width, height, matrix, true);
    }

    /**
     * 居中打印二维条码
     *
     * @param text:        二维码数据
     * @param print_size:  二维码块大小(单位:点, 取值 1 至 16 )
     * @param error_level: 二维码纠错等级(0 至 3)，
     *                     0 -- 纠错级别L ( 7%)，
     *                     1 -- 纠错级别M (15%)，
     *                     2 -- 纠错级别Q (25%)，
     *                     3 -- 纠错级别H (30%)
     */
    @ReactMethod
    public void printQRCode(String text, int print_size, int error_level, Callback successCallback, Callback failCallback) {
        int print_num = 0;//排列方式单个，双个
        if (isAidl) {
            AidlUtil.getInstance().printQr(text, print_size, error_level);
        } else {
            if (print_num == 0) {
                BluetoothUtil.sendData(ESCUtil.getPrintQRCode(text, print_size, error_level));
            } else {
                BluetoothUtil.sendData(ESCUtil.getPrintDoubleQRCode(text, text, print_size, error_level));
            }
        }
    }

    /**
     * 打印一维条码
     *
     * @param text:           条码数据
     * @param //symbology:    条码类型
     *                        0 -- UPC-A，
     *                        1 -- UPC-E，
     *                        2 -- JAN13(EAN13)，
     *                        3 -- JAN8(EAN8)，
     *                        4 -- CODE39，
     *                        5 -- ITF，
     *                        6 -- CODABAR，
     *                        7 -- CODE93，
     *                        8 -- CODE128
     * @param //height:       条码高度, 取值1到255, 默认162
     * @param //width:        条码宽度, 取值2至6, 默认2
     * @param //textposition: 文字位置 0--不打印文字, 1--文字在条码上方, 2--文字在条码下方, 3--条码上下方均打印
     */
    @ReactMethod
    public void printBarCode(String text, Callback successCallback, Callback failCallback) {
        int encode = 8;
        int height = 162;
        int width = 2;
        int position = 2;
        if (isAidl) {
            AidlUtil.getInstance().printBarCode(text, encode, height, width, position);
        } else {
            BluetoothUtil.sendData(ESCUtil.getPrintBarCode(text, encode, height, width, position));
            BluetoothUtil.sendData(ESCUtil.nextLine(3));

        }
    }

    /*
     * 打印表格头
     */
    @ReactMethod
    public void printTable(String type, Callback successCallback, Callback failCallback) {
        String[] text = new String[]{};
        int[] width = new int[]{};
        int[] align = new int[]{};
        if (type.equals("1")) {
            text = new String[]{"商品", "数量"};
            width = new int[]{30, 10};
            align = new int[]{0, 0};
        } else if (type.equals("2")) {
            text = new String[]{"商品", "数量", "单价", "金额"};
            width = new int[]{20, 8, 10, 10};
            align = new int[]{0, 0, 0, 0};
        }
        if (isAidl) {
            AidlUtil.getInstance().printOneTable(text, width, align);
        } else {
            BluetoothUtil.sendData(ESCUtil.printBitmap(BytesUtil.initTable(6, 12)));
        }

    }

    /*
     * 打印表格内容
     */
    @ReactMethod
    public void printContentTable(String text1, String text2, String text3, String text4, Callback successCallback, Callback failCallback) {
        String[] text = new String[]{text1, text2, text3, text4};
        int[] width = new int[]{20, 8, 10, 10};
        int[] align = new int[]{0, 0, 0, 0};
        if (isAidl) {
            AidlUtil.getInstance().printOneTable(text, width, align);
        } else {
            BluetoothUtil.sendData(ESCUtil.printBitmap(BytesUtil.initTable(6, 12)));
        }
    }

    /*
     * 打印表格内容
     */
    @ReactMethod
    public void printContentTable2(String text1, String text2, Callback successCallback, Callback failCallback) {
        String[] text = new String[]{text1, text2};
        int[] width = new int[]{30, 10};
        int[] align = new int[]{0, 0};
        if (isAidl) {
            AidlUtil.getInstance().printOneTable(text, width, align);
        } else {
            BluetoothUtil.sendData(ESCUtil.printBitmap(BytesUtil.initTable(6, 12)));
        }
    }

    /*
     * 打印表格列表
     */
    public void printTableList(ReadableMap goodsList, Callback successCallback, Callback failCallback) {
        Gson gs = new Gson();
//        Object detail = goodsList.toHashMap().get("goods");
        Object detail = goodsList.toHashMap();
        String listStr = gs.toJson(detail);
        List<TableItem> jsonListObject = gs.fromJson(listStr, new TypeToken<List<TableItem>>() {
        }.getType());//把JSON格式的字符串转为List

//        LinkedList<TableItem> datalist = new LinkedList<>();
        if (isAidl) {
            AidlUtil.getInstance().printTable(jsonListObject);
        } else {
            BluetoothUtil.sendData(ESCUtil.printBitmap(BytesUtil.initTable(6, 12)));
        }

    }


    /**************************************************************************************
     *课显相关方法总汇
     **************************************************************************************/

    /*
     * 副屏简易页面
     */
    @ReactMethod
    public void displaySimplePage(Callback successCallback, Callback failCallback) {
//        screenManager.init(this.myReactContext);
//        Display[] displays = screenManager.getDisplays();
//        Log.e(TAG, "屏幕数量" + displays.length);
//        for (int i = 0; i < displays.length; i++) {
//            Log.e(TAG, "屏幕" + displays[i]);
//        }
//        // 屏幕Display id 0: DisplayInfo{"内置屏幕", uniqueId "local:0", app 1920 x 1011, real 1920 x 1080,
//        // 屏幕Display id 1: DisplayInfo{"HDMI 屏幕", uniqueId "local:1", app 1024 x 600, real 1024 x 600,
//        Display display = screenManager.getPresentationDisplays();
//        if (display != null) {
//            videoDisplay = new VideoDisplay(getCurrentActivity(), display, Environment.getExternalStorageDirectory().getPath() + "/video_02.mp4");
//        }
        Intent intent = new Intent(this.myReactContext, TVActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getCurrentActivity().startActivity(intent);
//        MyBroadCastReceiver broadCastReceiver=new MyBroadCastReceiver();
    }

    private void printByBluTooth(String content) {
        try {
            if (isBold) {
                BluetoothUtil.sendData(ESCUtil.boldOn());
            } else {
                BluetoothUtil.sendData(ESCUtil.boldOff());
            }

            if (isUnderLine) {
                BluetoothUtil.sendData(ESCUtil.underlineWithOneDotWidthOn());
            } else {
                BluetoothUtil.sendData(ESCUtil.underlineOff());
            }

            if (record < 17) {
                BluetoothUtil.sendData(ESCUtil.singleByte());
                BluetoothUtil.sendData(ESCUtil.setCodeSystemSingle(codeParse(record)));
            } else {
                BluetoothUtil.sendData(ESCUtil.singleByteOff());
                BluetoothUtil.sendData(ESCUtil.setCodeSystem(codeParse(record)));
            }

            BluetoothUtil.sendData(content.getBytes(mStrings[record]));
            BluetoothUtil.sendData(ESCUtil.nextLine(3));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private byte codeParse(int value) {
        byte res = 0x00;
        switch (value) {
            case 0:
                res = 0x00;
                break;
            case 1:
            case 2:
            case 3:
            case 4:
                res = (byte) (value + 1);
                break;
            case 5:
            case 6:
            case 7:
            case 8:
            case 9:
            case 10:
            case 11:
                res = (byte) (value + 8);
                break;
            case 12:
                res = 21;
                break;
            case 13:
                res = 33;
                break;
            case 14:
                res = 34;
                break;
            case 15:
                res = 36;
                break;
            case 16:
                res = 37;
                break;
            case 17:
            case 18:
            case 19:
                res = (byte) (value - 17);
                break;
            case 20:
                res = (byte) 0xff;
                break;
        }
        return (byte) res;
    }


}