package it.integry.pointmobilescannerlibrary;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.view.KeyEvent;

import java.nio.charset.StandardCharsets;

import device.common.DecodeResult;
import device.common.ScanConst;
import device.sdk.ScanManager;
import it.integry.barcode_base_android_library.exception.BarcodeAdapterNotFoundException;
import it.integry.barcode_base_android_library.extension.RunnableArgs;
import it.integry.barcode_base_android_library.interfaces.BarcodeReaderInterface;
import it.integry.barcode_base_android_library.model.BarcodeScanDTO;
import it.integry.barcode_base_android_library.model.BarcodeType;

public class PointMobileBarcodeReader implements BarcodeReaderInterface {

    private final Context mApplicationContext;
    private static ScanManager mScanManager;
    private static DecodeResult mDecodeResult;

    private static RunnableArgs<BarcodeScanDTO> mOnScanSuccessfull;
    private static RunnableArgs<Exception> mOnScanFailed;

    private static String TAG = PointMobileBarcodeReader.class.getName();

    public PointMobileBarcodeReader(Context applicationContext) {
        this.mApplicationContext = applicationContext;

        mScanManager = new ScanManager();
        mDecodeResult = new DecodeResult();
    }

    @Override
    public boolean isRightAdapter() {
        try {
            mScanManager.aDecodeGetResultType();
            return true;
        } catch (Exception ex) {
            return false;
        }
    }

    @Override
    public void init(Runnable onDeviceReady) throws BarcodeAdapterNotFoundException {
        if(isRightAdapter()){
            try{
                mScanManager.aDecodeSetTerminator(ScanConst.Terminator.DCD_TERMINATOR_NONE);
                mScanManager.aDecodeSetResultType(ScanConst.ResultType.DCD_RESULT_USERMSG);

                onDeviceReady.run();
            } catch (Exception ex) {
                throw new BarcodeAdapterNotFoundException(getAdapterName());
            }
        } else {
            throw new BarcodeAdapterNotFoundException(getAdapterName());
        }
    }

    @Override
    public void deinit() {

    }

    @Override
    public void register(RunnableArgs<BarcodeScanDTO> onScanSuccessfull, RunnableArgs<Exception> onScanFailed) {
        mOnScanSuccessfull = onScanSuccessfull;
        mOnScanFailed = onScanFailed;
    }

    @Override
    public String getAdapterName() {
        return "PointMobile";
    }

    @Override
    public void onKeyEvent(KeyEvent keyEvent) {

    }


    public static class ScanResultReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (mScanManager != null) {
                if (ScanConst.INTENT_USERMSG.equals(intent.getAction())) {
                    mScanManager.aDecodeGetResult(mDecodeResult.recycle());

                    if (mOnScanSuccessfull != null) {

                        //try {
                            if(mDecodeResult.symName.equalsIgnoreCase("READ_FAIL")){
                                //if(mOnScanFailed != null) mOnScanFailed.run(new Exception("Barcode non riconosciuto"));
                                return;
                            }

                            if(mDecodeResult != null) {
                                String stringValue = null;

                                if(mDecodeResult.decodeValue != null && mDecodeResult.decodeValue.length > 0) {
                                    stringValue = new String(mDecodeResult.decodeValue, StandardCharsets.UTF_8);
                                }

                                BarcodeScanDTO barcodeScanDTO = new BarcodeScanDTO()
                                        .setByteValue(mDecodeResult.decodeValue)
                                        .setStringValue(stringValue)
                                        .setType(BarcodeType.fromInt(mDecodeResult.symType))
                                        .setName(mDecodeResult.symName)
                                        .setDecodingTime(mDecodeResult.decodeTimeMillisecond);

                                mOnScanSuccessfull.run(barcodeScanDTO);
                            }

                        //} catch (Exception ex) {
                        //    Log.e(TAG, ex.getMessage());

                        //    if(mOnScanFailed != null) mOnScanFailed.run(ex);
                        //}
                    }
                }
            }
        }
    }


}
