package com.hh.lib_dx_base_multi;

import static com.hh.lib_base.utils.StringUtils.DeleteElement;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

import com.donsee.bean.IDCardInfo;
import com.donsee.bean.SciCardInfo;
import com.donsee.devices.CardReader;
import com.donsee.devices.LogUtils;
import com.hh.lib_base.BaseApplication;
import com.hh.lib_base.log.AppLogUtils;
import com.hh.lib_dx_base_multi.bean.sscard.BaseSSCardBean;
import com.hh.lib_dx_base_multi.bean.InitStatusEnum;
import com.hh.lib_dx_base_multi.bean.sscard.SSCardConfig;
import com.hh.lib_dx_base_multi.listener.IDCardListener;
import com.hh.lib_dx_base_multi.listener.qr.QrResultListener;
import com.hh.lib_dx_base_multi.listener.sscard.SimpleSSCardResultListener;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;

/**
 * Description: 东信多合一读卡器
 * @author xwh
 * time 2024/9/11
 **/
public class DxCardReader {

    private volatile static DxCardReader instance;

   // private DxInitListener initListener;
    private UsbDevice usbDevice;
    private UsbManager usbManager;
    private PendingIntent mPendingIntent;

    //硬件厂商回复：多合一免驱的，都是这个固定的vid pid
    private int pid = 57407;
    private int vid = 1742;
    private final String ACTION_USB_PERMISSION = "com.hh.lib_dx_base_multi.USB_PERMISSION";
    long result = -1;

    private USBReceiver mUsbReceiver;
    private volatile CardReader cardReader;

    //东信多合一
    private CReaderThread cReaderDataThread;
    private volatile boolean isRuning = false;
    long beginTime=0;

    private volatile InitStatusEnum statusEnum = InitStatusEnum.DEFAULT;//设备是否初始化

    private static final int MESSAGE_RETRY_READER = 0x99; //重连
    private Handler mHandler;

    private SSCardConfig mSSConfig;  //社保卡配置
    private volatile SimpleSSCardResultListener simpleSSCardResultListener;  //社保卡结果返回
    private volatile IDCardListener idCardListener;   //身份证结果返回
    private volatile QrResultListener qrResultListener; //二维码返回监听
    private volatile HashMap<String,DxInitListener> initListenerMap;
    public static DxCardReader getInstance() {
        if (instance == null) {
            synchronized (DxCardReader.class) {
                if (instance == null) {
                    instance = new DxCardReader();

                }
            }
        }
        return instance;
    }

    public synchronized void init(Context context,String clazzName, DxInitListener listener) {
        if(initListenerMap==null){
            initListenerMap=new HashMap<>();
        }
        if (!TextUtils.isEmpty(clazzName) && listener != null) {
            initListenerMap.put(clazzName, listener);
        }
        if(cardReader==null) {
            synchronized (DxCardReader.class) {
                if (cardReader == null) {

                    cardReader = new CardReader(context);
                  //  initUSB(context);
                    initCardReader();
                   // registerReceiver(context);
                }
            }
        }

    }
    /**
     *
     * @author xwh
     * Time 2024/9/24
     * Description: 初始化东信阅读器
     *
    **/
    private synchronized void initCardReader(){
        synchronized (DxCardReader.class) {
            try {
                if (cardReader == null) {
                    return;
                }
                result = cardReader.Donsee_Open("USB");
                if (result == 0) {
                    if ( statusEnum != InitStatusEnum.SUCCESS) {
                        statusEnum = InitStatusEnum.SUCCESS;
                        initListenerCallback(true,result+"","");
                        startRead();
                    }
                } else {
                    if (statusEnum != InitStatusEnum.FAIL) {
                        statusEnum = InitStatusEnum.FAIL;
                        initListenerCallback(false,result+"", "读卡器初始化失败");
                        stopRead();
                    }
                    getmHandler().removeMessages(MESSAGE_RETRY_READER);
                    getmHandler().sendEmptyMessageDelayed(MESSAGE_RETRY_READER, 5000);
                }

              //  registerReceiver(BaseApplication.getContext());
            } catch (SecurityException e) {
                AppLogUtils.e(e.toString());
                getmHandler().removeMessages(MESSAGE_RETRY_READER);
                getmHandler().sendEmptyMessageDelayed(MESSAGE_RETRY_READER, 5000);
            } catch (Exception e) {
                getmHandler().removeMessages(MESSAGE_RETRY_READER);
                getmHandler().sendEmptyMessageDelayed(MESSAGE_RETRY_READER, 5000);
            }
        }

    }

    public CardReader getCardReader() {
        return cardReader;
    }

    /**
     * desc:初始化USB
     *
     * @author xia weihao
     * @date 2024/6/26
     */
    private void initUSB(Context mContext) {
        usbManager = (UsbManager) mContext.getApplicationContext().getSystemService(Context.USB_SERVICE);
        if (Build.VERSION.SDK_INT >= 31) {
            mPendingIntent = PendingIntent.getBroadcast(mContext, 0,
                    new Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_IMMUTABLE);
        } else {
            mPendingIntent = PendingIntent.getBroadcast(mContext, 0,
                    new Intent(ACTION_USB_PERMISSION), 0);
        }
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        mContext.registerReceiver(mUsbReceiver, filter);
        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
        if (!deviceList.isEmpty()) {
            for (UsbDevice next : deviceList.values()) {
                if (next.getVendorId() == vid && next.getProductId() == pid) {
                    usbDevice = next;
                    if (!usbManager.hasPermission(usbDevice)) {
                        usbManager.requestPermission(usbDevice, mPendingIntent);
                    } else {
                        initCardReader();
                    }
                }
            }
        }
    }

    /**
     *
     * @author xwh
     * Time 2024/9/11
     * Description: 是否初始化成功
     *
    **/
    public boolean isInitSuccessed(){
        return statusEnum==InitStatusEnum.SUCCESS;
    }

    public InitStatusEnum getStatusEnum() {
        return statusEnum;
    }

    /**
     * desc:注册USB监听广播
     *
     * @author xia weihao
     * @date 2024/6/26
     */
    public void registerReceiver(Context mContext) {
        IntentFilter filter = new IntentFilter();
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        mUsbReceiver = new USBReceiver();
        mContext.registerReceiver(mUsbReceiver, filter);
    }


    /**
     * desc:USB拔插广播
     *
     * @author xia weihao
     * @date 2024/6/26
     */
    private class USBReceiver extends BroadcastReceiver {
        private volatile  int usbResylt=0;
        @Override
        public void onReceive(Context context, Intent intent) {
            // 这里可以拿到插入的USB设备对象
            LogUtils.d("intent.getAction = " + intent.getAction());
            UsbDevice receiveDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            if (receiveDevice != null) {
                /*    private int pid = 57407;  private int vid = 1742;*/
                if (receiveDevice.getProductId() != pid || receiveDevice.getVendorId() != vid)
                    return;
            }
            switch (intent.getAction()) {
                case UsbManager.ACTION_USB_DEVICE_ATTACHED: // 插入USB设备
                    if (usbResylt == -1) {
                        if (cardReader == null) {
                            cardReader = new CardReader(context);
                        }
                       initCardReader();
                    }
                    usbResylt=0;

                    break;
                case UsbManager.ACTION_USB_DEVICE_DETACHED: // 拔出USB设备
                    usbDevice = null;
                    if (usbResylt == 0) {
                        usbDevice = null;
                        stopRead();
                        if (cardReader != null) {
                            cardReader.Donsee_Close();
                            cardReader = null;
                        }
                        usbResylt = -1;
                    }
                    break;
                case ACTION_USB_PERMISSION:
                    UsbDevice usbDevice1 = (UsbDevice) intent.getParcelableExtra("device");
                    if (intent.getBooleanExtra("permission", false) && usbDevice1 != null) {
                        initCardReader();
                    }
                    break;
                default:
                    break;
            }
        }
    }

    /**
     *
     * @author xwh
     * Time 2024/10/10
     * Description: 初始化结果回调
     *
    **/
    private void  initListenerCallback(boolean isInitSucced,String code,String errMsg){
        if(initListenerMap==null){
            return;
        }
        for (String key : initListenerMap.keySet()) {
            DxInitListener listener = initListenerMap.get(key);
            if(listener!=null){
                if(isInitSucced){
                    listener.initSuccess();
                }else{
                    listener.initFailed(code,errMsg);
                }
            }
        }

    }

    /**
     *
     * @author xwh
     * Time 2024/9/30
     * Description: 设置二维码返回监听
     *
    **/
    public void setQrResultListener(QrResultListener qrResultListener) {
        this.qrResultListener = qrResultListener;
    }

    /**
     *
     * @author xwh
     * Time 2024/9/24
     * Description: 社保卡配置
     *
    **/
    public void setmSSConfig(SSCardConfig mSSConfig) {
        this.mSSConfig = mSSConfig;
    }

    /**
     *
     * @author xwh
     * Time 2024/9/24
     * Description: 社保卡数据返回监听
     *
    **/
    public void setSimpleSSCardResultListener(SimpleSSCardResultListener simpleSSCardResultListener) {
        this.simpleSSCardResultListener = simpleSSCardResultListener;
    }

    /**
     *
     * @author xwh
     * Time 2024/9/24
     * Description: 身份证数据返回监听
     *
    **/
    public void setIdCardListener(IDCardListener idCardListener) {
        this.idCardListener = idCardListener;
    }



    /**
     *
     * @author xwh
     * Time 2024/9/24
     * Description: 循环线程（身份证、社保卡）
     *
    **/
    private class CReaderThread extends Thread {
        private final Object lock = new Object();
        private volatile boolean pause = false;

        public CReaderThread() {
        }

        void pauseThread() {
            pause = true;
        }

        void resumeThread() {
            pause = false;
            synchronized (lock) {
                lock.notifyAll();
            }
        }

        void onPause() {
            synchronized (lock) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void run() {
            super.run();
            while (isRuning) {
                while (pause) onPause();
                try {
                    readIDCard();
                    Thread.sleep(100);
                    readSSCard();
                    Thread.sleep(100);
                    readScanner();
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    pause=false;
                    isRuning=false;
                    cReaderDataThread=null;
                    e.printStackTrace();
                }

            }
        }
    }

    /**
     *
     * @author xwh
     * Time 2024/9/24
     * Description: 读取身份证
     *
    **/
    private void readIDCard() throws InterruptedException {
        if (!isInitSuccessed()) {
            return;
        }
        if (cardReader == null) {
            return;
        }
        IDCardInfo idCardInfo = new IDCardInfo();
        beginTime = System.currentTimeMillis();
        long result = cardReader.Donsee_ReadIDCard(1, idCardInfo);
        if (result == 0) {
            Thread.sleep(100);
            cardReader.Donsee_Beep(50);
            long time = System.currentTimeMillis() - beginTime;
            String readTime =""+time/1000+"."+time%1000+"s";
            if (idCardInfo.certType.equals("0")) {
                idCardInfo.certType = "居民身份证";
            } else if (idCardInfo.certType.equals("I")) {
                idCardInfo.certType = "外国人永久居留证";
            } else if (idCardInfo.certType.equals("J")) {
                idCardInfo.certType = "港澳台居民居住证";
            }
            if(idCardListener!=null){
                idCardListener.result(0,idCardInfo);
            }

        } else {
            if(idCardListener!=null){
                idCardListener.result(result,null);
            }
        }
    }







    /**
     *
     * desc:读取社保卡数据
     * @author xia weihao
     * @date 2024/6/26
     *
     */
    private void readSSCard() {
        if (!isInitSuccessed()) {
            return;
        }
        SciCardInfo sciCardInfo = new SciCardInfo();
        //nType 1，	有SAM卡返回全部信息   2，	无SAM卡返回卡号
        byte[] errInfor = new byte[256];
        SSCardConfig config = mSSConfig;
        if (config == null) {
            config = new SSCardConfig();
        }
        if (cardReader == null) {
            return;
        }
        long result = cardReader.Donsee_ReadSSCard(config.getSlotPSAM(), config.getnType(), sciCardInfo, errInfor);
        if (simpleSSCardResultListener != null && isRuning) {
            if (result == 0) {
                BaseSSCardBean info = new BaseSSCardBean();
                info.cardNumber = sciCardInfo.cardNO;
                info.name = sciCardInfo.name;
                info.sex = sciCardInfo.sex;
                info.nation = sciCardInfo.nation;
                info.idNumber = sciCardInfo.idNO;
                info.birthDate = sciCardInfo.birthDate;
                info.issueDate = sciCardInfo.issueDate;
                info.expireDate = sciCardInfo.expireDate;
                info.cityCode = sciCardInfo.cityCode;
                info.fullVersion = sciCardInfo.fullVersion;
                if(simpleSSCardResultListener!=null){
                    simpleSSCardResultListener.onSuccess(info);
                }

            } else {
                if(simpleSSCardResultListener!=null) {
                    simpleSSCardResultListener.onFail("读社保卡失败：" + CardReader.getErrorMessage(result));
                }
            }
        }

    }


    /**
     *
     * @author xwh
     * Time 2024/9/30
     * Description: 读取二维码
     *
     **/
    private void readScanner() {
        if(!DxCardReader.getInstance().isInitSuccessed()){
            Log.e("DxCardReader", "isInitSuccessed =false");
            return;
        }
        CardReader cardReader=DxCardReader.getInstance().getCardReader();
        if(cardReader==null){
            Log.e("DxCardReader","CardReader = null");
            return;
        }
        beginTime = System.currentTimeMillis();
        int[] len = new int[1];
        byte[] data = new byte[1024];
        long re;
        // 扫码模块，安卓建议扫码模组直接TTL串口接安卓主板更方便。或者用键盘监听模式。
        // 注意扫码有个超时等待入参，单位ms，超时等待时间内是中段的，读卡器无法进行其他读卡工作；
        // 根据不同码的密度，建议最低500~1000ms，时间越长，扫码成功率越高，但是相对整个轮询时间也会越长；
        re = cardReader.Donsee_ReadScannerInfo(1000,  len, data);
        long time = System.currentTimeMillis() - beginTime;
        String readTime =""+time/1000+"."+time%1000+"s";
        if (re == 0 && len[0]>0) {
            byte[] qrcode  = new byte[len[0]];
            System.arraycopy(data,0,qrcode,0,len[0]);
            try {
                String qrCodeStr = new String(DeleteElement(qrcode), "UTF-8");
                if(qrResultListener!=null){
                    qrResultListener.onSuccess(qrCodeStr);
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                if(qrResultListener!=null) {
                    qrResultListener.onFail(re + "", "不支持的编码");
                }
            }

        }else{
            if(qrResultListener!=null){
                qrResultListener.onFail( re+"",CardReader.getErrorMessage(re));
            }
        }
    }

    /**
     *
     * desc:启动东信读卡器轮询
     * @author xia weihao
     * @date 2024/6/26
     *
     */
    public synchronized void startRead() {

        if(cReaderDataThread!=null&&cReaderDataThread.isAlive()){
            return;
        }
        if(cReaderDataThread!=null){
            isRuning = false;
            cReaderDataThread.interrupt();
            cReaderDataThread = null;
        }
        if (cReaderDataThread == null) {
            cReaderDataThread = new CReaderThread();
        }
        isRuning = true;
        cReaderDataThread.start();

    }

    /**
     *
     * desc:停止东信读卡器读取
     * @author xia weihao
     * @date 2024/6/26
     *
     */
    public synchronized void stopRead() {
        if (cReaderDataThread == null) {
//            showString("请先启动读卡");
            return;
        }
        isRuning = false;
        cReaderDataThread.pause = false;
        cReaderDataThread.interrupt();
        cReaderDataThread = null;
    }



    /**
     * desc:销毁资源
     *
     * @author xia weihao
     * @date 2024/6/26
     */
    public void release() {
        stopRead();
     /*   if (mUsbReceiver != null) {
            context.unregisterReceiver(mUsbReceiver);
        }*/
        if (cardReader != null) {
            cardReader.Donsee_Close();
            cardReader.unregisterUSBReceiver();
            cardReader  =null;
        }
        instance =null;

    }

    public Handler getmHandler() {
        if (mHandler == null) {
            synchronized (DxCardReader.class) {
                if (mHandler == null) {
                    mHandler = new Handler(Looper.getMainLooper()) {
                        @Override
                        public void handleMessage(Message msg) {
                            switch (msg.what) {
                                case MESSAGE_RETRY_READER:
                                    initCardReader();
                                    break;
                                default:
                                    break;
                            }
                            super.handleMessage(msg);
                        }
                    };
                }
            }
        }
        return mHandler;
    }
}
