package cordova;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.graphics.RectF;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.Display;
import android.view.Gravity;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;

import androidx.appcompat.app.AppCompatActivity;

import com.scansolutions.mrzscannerlib.MRZResultModel;
import com.scansolutions.mrzscannerlib.MRZScanner;
import com.scansolutions.mrzscannerlib.MRZScannerListener;
import com.scansolutions.mrzscannerlib.ScannerType;


public class ScannerActivity extends AppCompatActivity implements MRZScannerListener {

    static int scannerType = 0;
    static MRZScannerListener mrzScannerListener;
    static boolean flashToggleActivated = false;
    static float sZoomFactor = 0f;

    static RectF sScanningRect;
    static MRZScannerDismissedListener mrzScannerDismissed;
    static ScannerActivityListener scannerActivityListener;
    static Boolean continuousScanningEnabled = false;
    private static Boolean ignoreDuplicates = true;
    private static Boolean extractIdBack = false;
    private static Boolean extractPassportFullImage = false;
    private static Boolean extractSignature = false;
    private static Boolean extractPortrait = false;

    private static Boolean showFlashButton = true;

    static Bitmap customOverlayBitmap;

  MRZScanner mrzScanner;

    public static void startScanner(Context context,
                                    Float zoomFactor,
                                    MRZScannerListener listener,
                                    MRZScannerDismissedListener mrzScannerDismissedListener) {
        startScanner(context, zoomFactor, listener, mrzScannerDismissedListener, new RectF(0, 0, 100, 100));
    }

    static void startScanner(Context context,
                             Float zoomFactor,
                             MRZScannerListener listener,
                             MRZScannerDismissedListener mrzScannerDismissedListener,
                             RectF partialRect) {
        ScannerActivity.mrzScannerDismissed = mrzScannerDismissedListener;
        sScanningRect = partialRect;
        mrzScannerListener = listener;
        sZoomFactor = zoomFactor;

        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(context, ScannerActivity.class);
                context.startActivity(intent);
            }
        });
    }

    public static void startScannerWithCustomOverlay(Context context,
                                                     Float zoomFactor,
                                                     MRZScannerListener listener,
                                                     String base64String,
                                                     MRZScannerDismissedListener mrzScannerDismissedListener) {
        startScannerWithCustomOverlay(context,zoomFactor, listener,base64String, mrzScannerDismissedListener, new RectF(0, 0, 100, 100));
    }

    static void startScannerWithCustomOverlay(Context context,
                                              Float zoomFactor,
                                              MRZScannerListener listener,
                                              String base64String,
                                              MRZScannerDismissedListener mrzScannerDismissedListener,
                                              RectF partialRect) {
        ScannerActivity.mrzScannerDismissed = mrzScannerDismissedListener;
        sScanningRect = partialRect;
        mrzScannerListener = listener;
        sZoomFactor = zoomFactor;

        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(context, ScannerActivity.class);
                if (base64String != null && !"".equals(base64String)) {
                    byte[] decodedBytes = android.util.Base64.decode(base64String, android.util.Base64.DEFAULT);
                    Bitmap customBitmap = BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
                    customOverlayBitmap = customBitmap;
                }
                context.startActivity(intent);
            }
        });

    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setUpWindow();

        super.onCreate(savedInstanceState);
        setContentView(this.getResources().getIdentifier("activity_start", "layout", getPackageName()));

        mrzScanner = (MRZScanner) getSupportFragmentManager().findFragmentByTag("MRZ_SCANNER_FRAGMENT");
        setupPartialView(mrzScanner);

        mrzScanner.setScannerType(ScannerType.values()[scannerType]);
        mrzScanner.setContinuousScanningEnabled(continuousScanningEnabled);
        mrzScanner.setIgnoreDuplicates(ignoreDuplicates);
        mrzScanner.setShowFlashButton(showFlashButton);
        mrzScanner.setCustomImageOverlay(customOverlayBitmap);
        MRZScanner.setExtractFullPassportImageEnabled(extractPassportFullImage);
        MRZScanner.setExtractIdBackImageEnabled(extractIdBack);
        MRZScanner.setExtractPortraitEnabled(extractPortrait);
        MRZScanner.setExtractSignatureEnabled(extractSignature);
        MRZScanner.setZoomFactor(sZoomFactor);

      if (flashToggleActivated) {
        mrzScanner.toggleFlash(true);
      }

        if (scannerActivityListener == null)
            scannerActivityListener = new ScannerActivityListener() {
                @Override
                public void closeScanner() {
                    ScannerActivity.this.finish();
                }

                @Override
                public void setContinuousScanningEnabled(Boolean enabled) {
                    if (mrzScanner != null) {
                        mrzScanner.setContinuousScanningEnabled(enabled);
                    }
                }

                @Override
                public void setIgnoreDuplicatesEnabled(Boolean enabled) {
                    if (mrzScanner != null) {
                        mrzScanner.setIgnoreDuplicates(enabled);
                    }
                }

                @Override
                public void resumeScanning() {
                    if (mrzScanner != null) {
                        mrzScanner.resumeScanning();
                    }
                }
            };
    }

    private void setUpWindow() {
        if (sScanningRect != null) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
            getWindow().requestFeature(Window.FEATURE_NO_TITLE);

            Point displaySize = getDisplaySize(ScannerActivity.this);
            WindowManager.LayoutParams lp = getWindow().getAttributes();
            lp.gravity = Gravity.TOP | Gravity.LEFT;
            lp.x = (int) (displaySize.x * (sScanningRect.left / 100.0f));
            lp.y = (int) (displaySize.y * (sScanningRect.top / 100.0f));
            lp.horizontalMargin = 0;
            lp.verticalMargin = 0;
            lp.width = (int) (displaySize.x * (sScanningRect.right / 100.0f));
            lp.height = (int) (displaySize.y * (sScanningRect.bottom / 100.0f));
            getWindow().setAttributes(lp);
        } else {
            setTheme(this.getResources().getIdentifier("Theme_AppCompat_NoActionBar", "style", getPackageName()));
        }
    }

    private void setupPartialView(MRZScanner mrzScanner) {
        if (sScanningRect != null) {
            Point displaySize = getDisplaySize(ScannerActivity.this);
            FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mrzScanner.getView().getLayoutParams();
            params.width = (int) (displaySize.x * (sScanningRect.right / 100.0f));
            params.height = (int) (displaySize.y * (sScanningRect.bottom / 100.0f));
            mrzScanner.getView().setLayoutParams(params);
        }
    }

    @Override
    public void successfulScanWithResult(MRZResultModel mrzResultModel) {
        mrzScannerListener.successfulScanWithResult(mrzResultModel);
        if (!continuousScanningEnabled)
            finish();
    }

    @Override
    public void successfulScanWithDocumentImage(Bitmap bitmap) {
        mrzScannerListener.successfulScanWithDocumentImage(bitmap);
        finish();
    }

    @Override
    public void successfulIdFrontImageScan(Bitmap fullImage, Bitmap portrait) {
        mrzScannerListener.successfulIdFrontImageScan(fullImage, portrait);
        finish();
    }

    @Override
    public void scanImageFailed() {
        mrzScannerListener.scanImageFailed();
        finish();
    }

    @Override
    public void permissionsWereDenied() {
        mrzScannerListener.permissionsWereDenied();
        finish();
    }

    private static Point getDisplaySize(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        final Point size = new Point();
        display.getSize(size);
        return size;
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        mrzScannerDismissed.scannerWasDismissed();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        scannerActivityListener = null;
        mrzScanner = null;
    }

    static void setExtractPortraitEnabled(Boolean enabled) {
        // Update boolean statically both in ScannerActivity and MRZScanner to make sure that
        // we handle this config method when called before and after mrzScanner is initialized
        // while providing default values declared in ScannerActivity that are different than the defaults in MRZScanner
        ScannerActivity.extractPortrait = enabled;
        MRZScanner.setExtractPortraitEnabled(enabled);
    }

    static void setExtractSignatureEnabled(Boolean enabled) {
        // Update boolean statically both in ScannerActivity and MRZScanner to make sure that
        // we handle this config method when called before and after mrzScanner is initialized
        // while providing default values declared in ScannerActivity that are different than the defaults in MRZScanner
        ScannerActivity.extractSignature = enabled;
        MRZScanner.setExtractSignatureEnabled(enabled);
    }

    static void setExtractFullPassportImageEnabled(Boolean enabled) {
        // Update boolean statically both in ScannerActivity and MRZScanner to make sure that
        // we handle this config method when called before and after mrzScanner is initialized
        // while providing default values declared in ScannerActivity that are different than the defaults in MRZScanner
        ScannerActivity.extractPassportFullImage = enabled;
        MRZScanner.setExtractFullPassportImageEnabled(enabled);
    }

    static void setExtractIdBackImageEnabled(Boolean enabled) {
        // Update boolean statically both in ScannerActivity and MRZScanner to make sure that
        // we handle this config method when called before and after mrzScanner is initialized
        // while providing default values declared in ScannerActivity that are different than the defaults in MRZScanner
        ScannerActivity.extractIdBack = enabled;
        MRZScanner.setExtractIdBackImageEnabled(enabled);
    }

    static void setContinuousScanningEnabled(Boolean enabled) {
        continuousScanningEnabled = enabled;
        if (scannerActivityListener != null) {
            scannerActivityListener.setContinuousScanningEnabled(enabled);
        }
    }

    static void setIgnoreDuplicatesEnabled(Boolean enabled) {
        ignoreDuplicates = enabled;
        if (scannerActivityListener != null) {
            scannerActivityListener.setIgnoreDuplicatesEnabled(enabled);
        }
    }

  public void toggleFlash(boolean toggleFlash) {
    if (mrzScanner != null) {
      mrzScanner.toggleFlash(toggleFlash);
    }
  }

  static void setShowFlashButton(Boolean show) {
    showFlashButton = show;
  }

}
