package com.common.print.many;

import android.content.Context;
import android.graphics.Bitmap;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.util.Log;

import com.common.print.bean.PrintBean;
import com.common.print.bean.PrintContentBean;
import com.common.print.many.base.IPrinter;
import com.common.print.callback.PrintInitResultCallback;
import com.common.print.utils.BitmapUtils;
import com.tx.printlib.Const;
import com.tx.printlib.UsbPrinter;

import java.util.List;
import java.util.Map;

/**
 *
 * 是乐易的打印机
 * 适用于以下设备
 * 马里奥-y9-80
 */
public class Mla80Printer implements IPrinter {


    // 当前类名
    public String mTag = "HHArome--"+getClass().getSimpleName() + "--";

    //用volatile关键字确保 instance 在多线程下的可见性
    private static volatile Mla80Printer instance = null;

    //将构造方法私有化，禁止外部通过构造方法创建实例
    private Mla80Printer() {
    }

    //提供一个公共的访问方法，用于获取该类的唯一实例
    public static Mla80Printer getInstance(Context context) {
        //如果instance为空，就进行实例化
        if (instance == null) {
            //保证多线程下只有一个线程进行实例化
            synchronized (Mla80Printer.class) {
                //第二次判断，避免多线程下创建多个实例
                if (instance == null) {
                    instance = new Mla80Printer(context);
                }
            }
        }
        return instance;
    }

    private Mla80Printer(Context context) {
        this.mContext = context;
    }


    Context mContext;

    private UsbPrinter mUsbPrinter;
    int vidpid[] = new int[]{0, 0};


    int retryCount = 0;
    boolean isInitSuccess;

    public void init(Context context) {

//        VID是，PID是

        if(mUsbPrinter==null){
            mUsbPrinter = new UsbPrinter(context.getApplicationContext());
        }


//        try{
//            vidpid=getvidpid("28E9","5812");
//        }
//        catch (NumberFormatException e){
//            Log.e(mTag,"PID或VID不是有效的16进制数");
//        }
//
//        final UsbDevice dev = getCorrectDevice(vidpid[0],vidpid[1]);
        final UsbDevice dev = getCorrectDevice();
        if (dev != null && mUsbPrinter.open(dev)) {

            mUsbPrinter.init();

            final long stat1 = mUsbPrinter.getStatus();
            final long stat2 = mUsbPrinter.getStatus2();
            Log.e(mTag, "stat1:" + stat1);
            Log.e(mTag, "stat2:" + stat2);
            // open()和close（）要配对使用
            mUsbPrinter.close();

            isInitSuccess = true;
            printInitResultCallback.onPrintInitSuccess();

        } else {
            Log.e(mTag, "找不到USB打印机");
            Log.e(mTag, "retryCount:"+retryCount);

            mUsbPrinter.close();

            if(retryCount <= 5){
                retryCount++;
                init(mContext);
            }else{
                isInitSuccess = false;
                printInitResultCallback.onPrintInitError("-1","找不到USB打印机，请检查USB线连接");
            }


        }


    }

    PrintInitResultCallback printInitResultCallback;

    @Override
    public void initPrint(PrintInitResultCallback printInitResultCallback) {

        this.printInitResultCallback = printInitResultCallback;

        init(mContext);

    }

    @Override
    public void printText(String text, int align, int textSize, boolean isBold) {

        Log.e(mTag,"isInitSuccess--"+isInitSuccess);

        // 恢复字体效果（大小、粗体等）为原始状态
        mUsbPrinter.resetFont();
        // 文字位置，左中右
        mUsbPrinter.doFunction(Const.TX_ALIGN, align, 0);
        // 文字加粗
        mUsbPrinter.doFunction(Const.TX_FONT_BOLD, isBold ? Const.TX_ON : Const.TX_OFF, 0);
        // 文字大小
        if (textSize > 26) {
            mUsbPrinter.doFunction(Const.TX_FONT_SIZE, Const.TX_SIZE_2X, Const.TX_SIZE_2X);
        } else {
            mUsbPrinter.doFunction(Const.TX_FONT_SIZE, Const.TX_SIZE_1X, Const.TX_SIZE_1X);
        }
        // 打印文字
        mUsbPrinter.outputStringLn(text);
        // 间隔
        feed(15);
        // 恢复字体效果（大小、粗体等）为原始状态
        mUsbPrinter.resetFont();

//        feed(15);


    }

    @Override
    public void printBarCode(String text, int width, int height) {
        mUsbPrinter.doFunction(Const.TX_BARCODE_HEIGHT, 15, 0);
        mUsbPrinter.printBarcode(Const.TX_BAR_UPCA, text);
    }

    @Override
    public void printQrCode(String text, int width, int height) {
        // 点大小
        mUsbPrinter.doFunction(Const.TX_QR_DOTSIZE, 6, 0);
        // 纠错等级
        mUsbPrinter.doFunction(Const.TX_QR_ERRLEVEL, Const.TX_QR_ERRLEVEL_M, 0); //27 for TX_QR_ERRLEVEL,0x32

        mUsbPrinter.printQRcode(text);
    }

    @Override
    public void printBitmap(final String base64, int width, int height) {
        //mUsbPrinter.printImage("/storage/sdcard0/a1.png");
//        mUsbPrinter.printImage(getExternalFilesDir(null).getPath()+"/../../../../a1.png");
//        mUsbPrinter.doFunction(Const.TX_UNIT_TYPE, Const.TX_UNIT_PIXEL, 0);


//        ThreadPoolManager.getInstance().executeIOTask(new Runnable() {
//            @Override
//            public void run() {

        feed(10);

                String picturePath = null;
                try {
                    picturePath = BitmapUtils.createPictureDirAndFile();
                    Log.e(mTag,"picturePath:"+picturePath);
                    Bitmap bitmap = BitmapUtils.stringToBitmap(base64);
                    BitmapUtils.saveImage(picturePath,bitmap);
                    Thread.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.e(mTag,"e:"+e.toString());
                }
//        String picturePath = "/storage/emulated/0/T1YB01_2024-05-16.png";
                try {
                    Log.e(mTag,"开始打印的picturePath:"+picturePath);
                    mUsbPrinter.doFunction(Const.TX_ALIGN, 1, 0);
                    mUsbPrinter.printImage(picturePath);
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.e(mTag,"e:"+e.toString());
                }

        feed(30);

//            }
//        });



//        mUsbPrinter.printImage(mContext.getExternalFilesDir(null).getPath()+"/../../../../a1.png");
//        mUsbPrinter.doFunction(Const.TX_UNIT_TYPE, Const.TX_UNIT_PIXEL, 0);



    }

    @Override
    public void printTextBitmap(List<PrintContentBean> printContentList, PrintBean.PrintConfigDTO printConfigDTO) {

    }

    @Override
    public void printBitmap(PrintBean.PrintConfigDTO printConfigDTO, String base64, int width, int height) {

    }

    @Override
    public void printPDF(PrintBean.PrintConfigDTO printConfigDTO, String localPath) {

    }


    @Override
    public void feed(int line) {
        // 走纸
        mUsbPrinter.doFunction(Const.TX_FEED, line, 0);

    }

    @Override
    public void cutPaper() {

        feed(30);
        mUsbPrinter.doFunction(Const.TX_FEED, 140, 0);
        mUsbPrinter.doFunction(Const.TX_CUT, Const.TX_PURECUT_FULL, 0);


        mUsbPrinter.close();

    }

    @Override
    public void disconnect() {

        if(mUsbPrinter!=null){
            mUsbPrinter.close();
        }

    }

    @Override
    public void startPrint() {

        // 每一次打印，都需要open下。等切纸时再close
        final UsbDevice dev = getCorrectDevice();
        if (dev != null && mUsbPrinter.open(dev)) {

            mUsbPrinter.init();

            final long stat1 = mUsbPrinter.getStatus();
            final long stat2 = mUsbPrinter.getStatus2();
            Log.e(mTag, "startPrint--stat1:" + stat1);
            Log.e(mTag, "startPrint--stat2:" + stat2);
            // 不再close,等打印完再close


        } else {
            Log.e(mTag, "startPrint--找不到USB打印机");

            mUsbPrinter.close();

            // 再试下
            final UsbDevice dev2 = getCorrectDevice();
            if (dev2 != null && mUsbPrinter.open(dev2)) {

                mUsbPrinter.init();
                final long stat1 = mUsbPrinter.getStatus();
                final long stat2 = mUsbPrinter.getStatus2();
                Log.e(mTag, "startPrint--stat1:" + stat1);
                Log.e(mTag, "startPrint--stat2:" + stat2);
            }


        }

    }


    private UsbDevice getCorrectDevice() {
        final UsbManager usbMgr = (UsbManager) (mContext.getSystemService(Context.USB_SERVICE));
        final Map<String, UsbDevice> devMap = usbMgr.getDeviceList();
        for (String name : devMap.keySet()) {
            Log.e(mTag, "check device: " + name);
            if (UsbPrinter.checkPrinter(devMap.get(name)))
                return devMap.get(name);
        }
        return null;
    }


    private UsbDevice getCorrectDevice(int vid, int pid) {
        final UsbManager usbMgr = (UsbManager) (mContext.getSystemService(Context.USB_SERVICE));
        final Map<String, UsbDevice> devMap = usbMgr.getDeviceList();
        for (String name : devMap.keySet()) {
            Log.e(mTag, "check device: " + name);
            //devMap.get(name).getProductId() devMap.get(name).getVendorId()
            if (vid != 0 && pid != 0) {
                if (devMap.get(name).getVendorId() != vid || devMap.get(name).getProductId() != pid) {
                    continue;
                }
            }
            if (UsbPrinter.checkPrinter(devMap.get(name)))
                return devMap.get(name);
        }
        return null;
    }

    public static int[] getvidpid(String vidstr, String pidstr) {
        int vid = 0, pid = 0;
        if (!vidstr.isEmpty() && !pidstr.isEmpty()) {
            vid = Integer.parseInt(vidstr, 16);
            pid = Integer.parseInt(pidstr, 16);
        }
        return new int[]{vid, pid};
    }


}
