
package com.cqsmart.library;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import androidx.annotation.NonNull;
import android.util.Base64;
import android.util.Log;

import com.baidu.ocr.sdk.OnResultListener;
import com.baidu.ocr.sdk.exception.OCRError;
import com.baidu.ocr.sdk.model.AccessToken;

import com.baidu.ocr.sdk.model.BankCardParams;
import com.baidu.ocr.sdk.model.OcrRequestParams;

import com.baidu.ocr.sdk.model.BankCardResult;
import com.baidu.ocr.sdk.model.OcrResponseResult;
import com.facebook.common.activitylistener.BaseActivityListener;
import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.BaseActivityEventListener;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import com.baidu.ocr.sdk.OCR;
import com.baidu.ocr.sdk.OnResultListener;
import com.baidu.ocr.sdk.exception.OCRError;
import com.baidu.ocr.sdk.model.IDCardParams;
import com.baidu.ocr.sdk.model.IDCardResult;
import com.baidu.ocr.ui.camera.CameraNativeHelper;
import com.baidu.ocr.ui.camera.CameraView;
import com.baidu.ocr.ui.camera.CameraActivity;
import com.facebook.react.bridge.WritableMap;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
//import com.baidu.ocr.ui.camera.;


public class RNBaiduAiModule extends ReactContextBaseJavaModule {

  private final ReactApplicationContext reactContext;
  private static final int REQUEST_CODE_CAMERA = 102;
  private static final int REQUEST_CODE_PICK_IMAGE_FRONT = 201;
  private static final int REQUEST_CODE_PICK_IMAGE_BACK = 202;
  private static final int REQUEST_CODE_BANKCARD = 111;
  private static final int REQUEST_CODE_LICENSE_PLATE = 122;
  private static final int REQUEST_CODE_QRCODE = 127;
  private Promise resultPromise;
  private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener(){



    private String getRealPathFromURI(Uri contentURI) {
      String result;
      Cursor cursor = getCurrentActivity().getContentResolver().query(contentURI, null, null, null, null);
      if (cursor == null) { // Source is Dropbox or other similar local file path
        result = contentURI.getPath();
      } else {
        cursor.moveToFirst();
        int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
        result = cursor.getString(idx);
        cursor.close();
      }
      return result;
    }

    @Override
    public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
      Log.i("request::::::::::::::", String.valueOf(resultCode));

      if (data != null) {
        String contentType = data.getStringExtra(CameraActivity.KEY_CONTENT_TYPE);
        String filePath = ImageFileUtil.getSaveFile(getReactApplicationContext()).getAbsolutePath();
        if (CameraActivity.CONTENT_TYPE_ID_CARD_FRONT.equals(contentType)&&requestCode == REQUEST_CODE_CAMERA && resultCode == Activity.RESULT_OK) {

          recIDCard(IDCardParams.ID_CARD_SIDE_FRONT, filePath);
        } else if (CameraActivity.CONTENT_TYPE_ID_CARD_BACK.equals(contentType)&&requestCode == REQUEST_CODE_CAMERA && resultCode == Activity.RESULT_OK) {

          recIDCard(IDCardParams.ID_CARD_SIDE_BACK, filePath);
        }

      }
      if (requestCode == REQUEST_CODE_BANKCARD && resultCode == Activity.RESULT_OK) {
        String filePath = ImageFileUtil.getSaveFile(getReactApplicationContext()).getAbsolutePath();
        recBank(filePath, resultPromise);
      }
      if(requestCode == REQUEST_CODE_LICENSE_PLATE && resultCode == Activity.RESULT_OK){
        String filePath = ImageFileUtil.getSaveFile(getReactApplicationContext()).getAbsolutePath();
        recLicensePlate(filePath);
      }
      if(resultCode==Activity.RESULT_CANCELED&&requestCode == REQUEST_CODE_CAMERA){
        resultPromise.reject("-1","scan fail");
        return;
      }
    }

  };
  public RNBaiduAiModule(ReactApplicationContext reactContext) {
    super(reactContext);
    this.reactContext = reactContext;
    reactContext.addActivityEventListener(mActivityEventListener);

  }

  private void recLicensePlate(final String filePath){
    OcrRequestParams param = new OcrRequestParams();
    param.setImageFile(new File(filePath));
    OCR.getInstance().recognizeLicensePlate(param,new OnResultListener<OcrResponseResult>() {
      @Override
      public void onResult(OcrResponseResult result) {
        if(result !=null){
          Log.i("filePath::::::::::::::",result.toString());
          String imageData = getBase64StringFromFile(filePath);
          WritableMap response = Arguments.createMap();
          response.putString("base64",imageData);
          response.putString("filePath",filePath);
          response.putString("data",result.getJsonRes());
          resultPromise.resolve(response);
        }else{
          resultPromise.reject("-1","识别错误");
        }
        }

      @Override
      public void onError(OCRError ocrError) {
        resultPromise.reject("-1","识别错误");
      }
    });
  }


  private void recIDCard(String idCardSide, final String filePath) {

    IDCardParams param = new IDCardParams();
    Log.i("filePath::::::::::::::",filePath);
    param.setImageFile(new File(filePath));
    // 设置身份证正反面
    param.setIdCardSide(idCardSide);
    // 设置方向检测
    param.setDetectDirection(true);
    // 设置图像参数压缩质量0-100, 越大图像质量越好但是请求时间越长。 不设置则默认值为20
    param.setImageQuality(20);

    OCR.getInstance().recognizeIDCard(param, new OnResultListener<IDCardResult>() {
      @Override
      public void onResult(IDCardResult result) {

        if (result != null) {
          WritableMap response = Arguments.createMap();
          WritableMap finalResult = Arguments.createMap();
//          // 只能一个个封装
//          WritableMap item1 = Arguments.createMap();
//          item1.putString("words", result.getName().toString());
//          finalResult.putMap("姓名", item1);
//
//          WritableMap item2 = Arguments.createMap();
//          item2.putString("words", result.getIdNumber().toString());
//          finalResult.putMap("公民身份号码", item2);
//
//          WritableMap item3 = Arguments.createMap();
//          item3.putString("words", result.getGender().toString());
//          finalResult.putMap("性别", item3);
//
//          WritableMap item4 = Arguments.createMap();
//          item4.putString("words", result.getEthnic().toString());
//          finalResult.putMap("民族", item4);
//
//          WritableMap item5 = Arguments.createMap();
//          item5.putString("words", result.getAddress().toString());
//          finalResult.putMap("住址", item5);
//
//          WritableMap item7 = Arguments.createMap();
//          item7.putString("words", result.getExpiryDate().toString());
//          finalResult.putMap("过期时间", item7);
//
//          WritableMap item8 = Arguments.createMap();
//          item8.putString("words", result.getSignDate().toString());
//          finalResult.putMap("签发时间", item8);
          String imageData = getBase64StringFromFile(filePath);
          WritableMap item6 = Arguments.createMap();
          item6.putString("filePath", filePath);
          item6.putString("data", imageData);
          finalResult.putMap("image", item6);

          WritableMap item9 = Arguments.createMap();
          item9.putString("words", result.getJsonRes());
          finalResult.putMap("data", item9);
          response.putMap("result", finalResult);
          Log.i("JSON:::::",result.getJsonRes());
//          CameraNativeHelper.release();
            if(resultPromise != null){
              resultPromise.resolve(response);
            }

        }else{
          CameraNativeHelper.release();
          if(resultPromise != null){
            resultPromise.reject("-1","scan fail");
          }

        }
//        CameraNativeHelper.release();
      }

      @Override
      public void onError(OCRError error) {
//        alertText("", error.getMessage());
//        CameraNativeHelper.release();
      }
    });
  }

  private void putExtraFileInfo(@NonNull final String path,
                                WritableMap response) {
    // size && filename
    try {
      File f = new File(path);
      response.putDouble("fileSize", f.length());
      response.putString("fileName", f.getName());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  private String getBase64StringFromFile(String absoluteFilePath) {
    InputStream inputStream = null;
    try {
      inputStream = new FileInputStream(new File(absoluteFilePath));
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    }

    byte[] bytes;
    byte[] buffer = new byte[8192];
    int bytesRead;
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    try {
      while ((bytesRead = inputStream.read(buffer)) != -1) {
        output.write(buffer, 0, bytesRead);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    bytes = output.toByteArray();
    return Base64.encodeToString(bytes, Base64.NO_WRAP);
  }

  @Override
  public String getName() {
    return "RNBaiduAi";
  }
  public static void recBank(final String filePath,final Promise promise) {
    BankCardParams param = new BankCardParams();
    param.setImageFile(new File(filePath));
    OCR.getInstance().recognizeBankCard(param, new OnResultListener<BankCardResult>() {
      @Override
      public void onResult(BankCardResult result) {
        WritableMap response = Arguments.createMap();
        WritableMap finalResult = Arguments.createMap();
        WritableMap item1 = Arguments.createMap();
        item1.putString("words", result.getJsonRes());
        finalResult.putMap("data", item1);

        WritableMap item6 = Arguments.createMap();
        item6.putString("filePath", filePath);
        finalResult.putMap("image", item6);
        Log.i("bank::::::",result.getJsonRes());
        response.putMap("result", finalResult);
        if(promise != null){
          promise.resolve(response);
        }


      }

      @Override
      public void onError(OCRError error) {
        if(promise != null){
          promise.reject("-1","Error");
        }

      }
    });
  }
  @ReactMethod
  public void releaseCameraModel(){
    CameraNativeHelper.release();
  }
  @ReactMethod
  public void authWithAKSK(String apiKey, String secretKey, final Promise promiseHandler){
    Log.i("code:::::::",apiKey);
    OCR.getInstance().initAccessTokenWithAkSk(new OnResultListener<AccessToken>() {
      @Override
      public void onResult(AccessToken accessToken) {

        String token = accessToken.getAccessToken();
        Log.i("code:::::::",token);
        CameraNativeHelper.init(getCurrentActivity(), OCR.getInstance().getLicense(),
                new CameraNativeHelper.CameraNativeInitCallback() {

                  @Override
                  public void onError(int errorCode, Throwable e) {
                    String msg ;
                    switch (errorCode){
                      case CameraView.NATIVE_AUTH_INIT_SUCCESS:
                        promiseHandler.resolve("success");
                      case CameraView.NATIVE_SOLOAD_FAIL:
                        msg="加载so失败";
                        break;
                      case CameraView.NATIVE_AUTH_FAIL:
                        msg="token获取失败!";
                        break;
                      case CameraView.NATIVE_INIT_FAIL:
                        msg="本地质量控制";
                        break;
                      default:
                        msg=String.valueOf(errorCode);

                    }
                    promiseHandler.reject("-1",msg);
                  }
                });

      }

      @Override
      public void onError(OCRError ocrError) {
        Log.v("OCR Error:",ocrError.getMessage());

      }
    },reactContext,apiKey,secretKey);

  }

  @ReactMethod
  public void scanBankCard(boolean isTrue,final Promise promise)
  {
    resultPromise=promise;
    Intent intent = new Intent(getCurrentActivity(),CameraActivity.class);
    intent.putExtra(CameraActivity.KEY_OUTPUT_FILE_PATH, ImageFileUtil.getSaveFile(getReactApplicationContext()).getAbsolutePath());

    intent.putExtra(CameraActivity.KEY_CONTENT_TYPE, CameraActivity.CONTENT_TYPE_BANK_CARD);
    getCurrentActivity().startActivityForResult(intent, REQUEST_CODE_BANKCARD);
  }

  @ReactMethod
  public void scanIdCard (boolean isFront ,final Promise promise){

    resultPromise=promise;
    Intent intent = new Intent(getCurrentActivity(),CameraActivity.class);
    intent.putExtra(CameraActivity.KEY_OUTPUT_FILE_PATH, ImageFileUtil.getSaveFile(getReactApplicationContext()).getAbsolutePath());
    intent.putExtra(CameraActivity.KEY_NATIVE_ENABLE,
            true);
    intent.putExtra(CameraActivity.KEY_NATIVE_MANUAL,
            true);
    if(isFront){
      intent.putExtra(CameraActivity.KEY_CONTENT_TYPE, CameraActivity.CONTENT_TYPE_ID_CARD_FRONT);
    }else{
      intent.putExtra(CameraActivity.KEY_CONTENT_TYPE, CameraActivity.CONTENT_TYPE_ID_CARD_BACK);
    }

    getCurrentActivity().startActivityForResult(intent, REQUEST_CODE_CAMERA);
  }

  @ReactMethod
  public void scanLicensePlate( final Promise promise){
    resultPromise=promise;
    Intent intent = new Intent(getCurrentActivity(), CameraActivity.class);
    intent.putExtra(CameraActivity.KEY_OUTPUT_FILE_PATH,
            ImageFileUtil.getSaveFile(getReactApplicationContext()).getAbsolutePath());
    intent.putExtra(CameraActivity.KEY_CONTENT_TYPE,
            CameraActivity.CONTENT_TYPE_GENERAL);
    getCurrentActivity().startActivityForResult(intent, REQUEST_CODE_LICENSE_PLATE);
  }



}
