package io.scanbot.sdk.reactnative.ui;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;

import com.facebook.react.bridge.BaseActivityEventListener;
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.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;

import java.util.Random;

import io.scanbot.sdk.reactnative.ResultProxyDelegate;
import io.scanbot.sdk.reactnative.ScanbotSDKReactNative;
import io.scanbot.sdk.sdk_native_wrapper.SBNWReadyToUseUi;
import io.scanbot.sdk.sdk_native_wrapper.SBNWReadyToUseUiKt;
import io.scanbot.sdk.sdk_native_wrapper.wrapper.ui.SBNWRtuBarcodeScanner;
import io.scanbot.sdk.sdk_native_wrapper.wrapper.ui.SBNWRtuBarcodesBatchScanner;
import io.scanbot.sdk.sdk_native_wrapper.wrapper.ui.SBNWRtuCroppingScreen;
import io.scanbot.sdk.sdk_native_wrapper.wrapper.ui.SBNWRtuDocumentScanner;
import io.scanbot.sdk.sdk_native_wrapper.wrapper.ui.SBNWRtuEhicScanner;
import io.scanbot.sdk.sdk_native_wrapper.wrapper.ui.SBNWRtuGenericDocumentRecognizer;
import io.scanbot.sdk.sdk_native_wrapper.wrapper.ui.SBNWRtuLicensePlateScanner;
import io.scanbot.sdk.sdk_native_wrapper.wrapper.ui.SBNWRtuMedicalCertificateScanner;
import io.scanbot.sdk.sdk_native_wrapper.wrapper.ui.SBNWRtuMrzScanner;
import io.scanbot.sdk.sdk_native_wrapper.wrapper.ui.SBNWRtuTextDataScanner;
import io.scanbot.sdk.sdk_native_wrapper.wrapper.ui.base.SBNWRtuWrapper;
import kotlin.NotImplementedError;

public class DefaultUiModule extends ReactContextBaseJavaModule {

    public DefaultUiModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @Override
    public String getName() {
        return "SBSDKDefaultUi";
    }

    private static final SBNWReadyToUseUi readyToUseUi = ScanbotSDKReactNative.getReadyToUseUi();

    @ReactMethod
    public void startDocumentScanner(ReadableMap configuration, final Promise promise) {
        final SBNWRtuDocumentScanner rtuWrapper = SBNWReadyToUseUiKt.withConfiguration(new SBNWRtuDocumentScanner(), configuration.toHashMap());
        startRtuUiActivity(rtuWrapper, promise);
    }

    @ReactMethod
    public void closeDocumentScanner(final Promise promise) {
        closeRtuUiActivity(readyToUseUi.getDocumentScanner(), promise);
    }

    @ReactMethod
    public void startCroppingScreen(ReadableMap page, ReadableMap configuration, final Promise promise) {
        final SBNWRtuCroppingScreen rtuWrapper = SBNWReadyToUseUiKt.withConfiguration(new SBNWRtuCroppingScreen(), page.toHashMap(), configuration.toHashMap());
        startRtuUiActivity(rtuWrapper, promise);
    }

    @ReactMethod
    public void closeCroppingScreen(final Promise promise) {
        closeRtuUiActivity(readyToUseUi.getCroppingScreen(), promise);

    }

    @ReactMethod
    public void startMrzScanner(ReadableMap configuration, final Promise promise) {
        final SBNWRtuMrzScanner rtuWrapper = SBNWReadyToUseUiKt.withConfiguration(new SBNWRtuMrzScanner(), configuration.toHashMap());
        startRtuUiActivity(rtuWrapper, promise);
    }

    @ReactMethod
    public void closeMrzScanner(final Promise promise) {
        closeRtuUiActivity(readyToUseUi.getMrzScanner(), promise);
    }

    @ReactMethod
    private void startMedicalCertificateScanner(ReadableMap configuration, final Promise promise) {
        final SBNWRtuMedicalCertificateScanner rtuWrapper = SBNWReadyToUseUiKt.withConfiguration(new SBNWRtuMedicalCertificateScanner(), configuration.toHashMap());
        startRtuUiActivity(rtuWrapper, promise);
    }

    @ReactMethod
    private void startGenericDocumentRecognizer(ReadableMap configuration, final Promise promise) {
        final SBNWRtuGenericDocumentRecognizer rtuWrapper = SBNWReadyToUseUiKt.withConfiguration(new SBNWRtuGenericDocumentRecognizer(), configuration.toHashMap());
        startRtuUiActivity(rtuWrapper, promise);
    }

    @ReactMethod
    private void startEHICScanner(ReadableMap configuration, final Promise promise) {
        final SBNWRtuEhicScanner rtuWrapper = SBNWReadyToUseUiKt.withConfiguration(new SBNWRtuEhicScanner(), configuration.toHashMap());
        startRtuUiActivity(rtuWrapper, promise);
    }

    @ReactMethod
    public void closeEHICScanner(final Promise promise) {
        closeRtuUiActivity(readyToUseUi.getEhicScanner(), promise);
    }

    @ReactMethod
    public void startBarcodeScanner(ReadableMap configuration, final Promise promise) {
        final SBNWRtuBarcodeScanner rtuWrapper = SBNWReadyToUseUiKt.withConfiguration(new SBNWRtuBarcodeScanner(), configuration.toHashMap());
        startRtuUiActivity(rtuWrapper, promise);
    }

    @ReactMethod
    public void closeBarcodeScanner(final Promise promise) {
        closeRtuUiActivity(readyToUseUi.getBarcodeScanner(), promise);
    }

    @ReactMethod
    public void startLicensePlateScanner(ReadableMap configuration, final Promise promise) {
        final SBNWRtuLicensePlateScanner rtuWrapper = SBNWReadyToUseUiKt.withConfiguration(new SBNWRtuLicensePlateScanner(), configuration.toHashMap());
        startRtuUiActivity(rtuWrapper, promise);
    }

    @ReactMethod
    public void closeLicensePlateScanner(final Promise promise) {
        closeRtuUiActivity(readyToUseUi.getLicensePlateScanner(), promise);
    }

    @ReactMethod
    public void startBatchBarcodeScanner(ReadableMap configuration, final Promise promise) {
        final SBNWRtuBarcodesBatchScanner rtuWrapper = SBNWReadyToUseUiKt.withConfiguration(new SBNWRtuBarcodesBatchScanner(), configuration.toHashMap());
        startRtuUiActivity(rtuWrapper, promise);
    }

    @ReactMethod
    public void closeBatchBarcodeScanner(final Promise promise) {
        closeRtuUiActivity(readyToUseUi.getBarcodesBatchScanner(), promise);
    }

    @ReactMethod
    public void startTextDataScanner(final ReadableMap configuration, final Promise promise) {
        SBNWRtuTextDataScanner rtuWrapper;
        try {
            rtuWrapper = SBNWReadyToUseUiKt.withConfiguration(new SBNWRtuTextDataScanner(), configuration.toHashMap());
            startRtuUiActivity(rtuWrapper, promise);
        } catch (Exception e) {
            promise.reject(e);
        }
    }

    @ReactMethod
    public void closeTextDataScanner(final Promise promise) {
        closeRtuUiActivity(readyToUseUi.getTextDataScanner(), promise);
    }

    private void sendEvent(String eventName, WritableMap params) {
        getReactApplicationContext()
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit(eventName, params);
    }

    @SuppressWarnings("rawtypes")
    void startRtuUiActivity(final SBNWRtuWrapper scannerWrapper, final Promise promise) {
        final ReactApplicationContext context = getReactApplicationContext();
        Intent intent = scannerWrapper.createIntent(context);

        Random random = new Random();
        final int code = random.nextInt(9999);

        final BaseActivityEventListener listener = new BaseActivityEventListener() {
            @Override
            public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
                super.onActivityResult(activity, requestCode, resultCode, data);

                if (requestCode == code) {
                    context.removeActivityEventListener(this);
                    scannerWrapper.handleResult(new ResultProxyDelegate(promise), resultCode, data);
                }
            }
        };

        context.addActivityEventListener(listener);
        context.startActivityForResult(intent, code, null);
    }

    @SuppressWarnings("rawtypes")
    void closeRtuUiActivity(SBNWRtuWrapper scannerWrapper, final Promise promise) {
        scannerWrapper.close(getReactApplicationContext());
        promise.resolve(null);
    }
}