package com.vntel.cccd.processor;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.os.AsyncTask;
import android.util.Log;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.ReactMethod;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.mlkit.vision.common.InputImage;
import com.google.mlkit.vision.text.Text;
import com.google.mlkit.vision.text.TextRecognizer;
import com.google.mlkit.vision.text.latin.TextRecognizerOptions;
import com.htc.sdk.IDCardReader;
import com.htc.sdk.model.MRZInfo;
import com.htc.sdk.model.MRZResult;
import com.htc.sdk.mrzparser.TextRecognition;
import com.htc.sdk.mrzparser.TextRecognitionListener;
import com.otaliastudios.cameraview.CameraUtils;
import com.otaliastudios.cameraview.frame.Frame;
import com.otaliastudios.cameraview.frame.FrameProcessor;
import com.otaliastudios.cameraview.internal.CropHelper;
import com.otaliastudios.cameraview.size.AspectRatio;
import com.otaliastudios.cameraview.size.Size;

import java.io.ByteArrayOutputStream;

public class MRZFrameProcessor implements FrameProcessor {
    private Rect mCameraFrame;
    private Rect mFocusFrame;
    private MRZFrameProcessorDelegate mDelegate;

    public MRZFrameProcessor(Context context,
                             Rect cameraFrame,
                             Rect focusFrame,
                             MRZFrameProcessorDelegate delegate) {
        this.mCameraFrame = cameraFrame;
        this.mFocusFrame = focusFrame;
        this.mDelegate = delegate;

    }
    public void cancel() {

    }

    private Bitmap croppedFocusImage(@NonNull Frame frame) {
        byte[] data = frame.getData();
        Size s = frame.getSize();
        YuvImage yuv = new YuvImage(data, ImageFormat.NV21, s.getWidth(), s.getHeight(), null);
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        yuv.compressToJpeg(new Rect(0, 0, s.getWidth(), s.getHeight()), 100, stream);
        byte[] buf = stream.toByteArray();
        int rotation = frame.getRotationToView();
        Bitmap source = CameraUtils.decodeBitmap(buf);
        Matrix transform = new Matrix();
        transform.postRotate(rotation);
        Bitmap normalizedImage = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), transform, true);
        AspectRatio cameraViewRatio = AspectRatio.of(mCameraFrame.width(), mCameraFrame.height());
        Rect cropRect = CropHelper.computeCrop(new Size(normalizedImage.getWidth(), normalizedImage.getHeight()), cameraViewRatio);

        int focusLeft = Math.round(mFocusFrame.left * (float)cropRect.width() / mCameraFrame.width());
        int focusTop = Math.round((mFocusFrame.top - mCameraFrame.top) * (float)cropRect.height() / mCameraFrame.height());
        cropRect.top += focusTop;
        cropRect.left += focusLeft;
        cropRect.bottom -= focusTop;
        cropRect.right -= focusLeft;
        return Bitmap.createBitmap(normalizedImage, cropRect.left, cropRect.top, cropRect.width(), cropRect.height());
    }

    @Override
    public void process(@NonNull Frame frame) {
        Bitmap mrzImage = croppedFocusImage(frame);
        TextRecognizer recognizer = com.google.mlkit.vision.text.TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS);
        InputImage image = InputImage.fromBitmap(mrzImage, 0);
        Task<Text> result =
                recognizer.process(image)
                        .addOnSuccessListener(new OnSuccessListener<Text>() {
                            @Override
                            public void onSuccess(Text visionText) {
                                // Task completed successfully
                                // ...
                                try {
                                    IDCardReader mCardReader = new IDCardReader();
                                    String mrzText = visionText.getText();
                                    MRZResult result = mCardReader.parseMRZImage(mrzText, mrzImage);
                                    if (result != null) {
                                        if (mDelegate != null) {
                                            mDelegate.onRecognizedMRZ(result, new MRZInfo(mrzText));
                                        }
                                    }
                                } catch (Exception ex) {
                                    Log.e("MRZ", ex.toString());
                                }

                            }
                        });
    }
}
