package com.contentsquare.rn;

import com.contentsquare.rn.BuildConfig;
import com.contentsquare.rn.NativeContentsquareModuleSpec;
import com.contentsquare.rn.csq.CSQTransitionWrapper;
import com.contentsquare.rn.csq.LegacyTransitionWrapper;
import com.contentsquare.rn.csq.TransitionWrapperInterface;
import com.contentsquare.rn.eventEmitter.CSEventEmitterModuleImpl;
import com.contentsquare.rn.utils.ReactNativeUiThreadUtil;
import com.contentsquare.rn.utils.ReactNativeViewFinder;
import com.contentsquare.rn.webview.WebViewInjector;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.Promise;

import android.util.Log;

import java.util.Map;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public class ContentsquareModule extends NativeContentsquareModuleSpec {

    private TransitionWrapperInterface implementation;
    private final CSQTransitionWrapper csqTransitionWrapper;

    public ContentsquareModule(
            ReactApplicationContext reactContext,
            WebViewInjector webViewInjector,
            CSEventEmitterModuleImpl csEventEmitterModuleImpl,
            ReactNativeUiThreadUtil reactNativeUiThreadUtil,
            ReactNativeViewFinder reactNativeViewFinder) {
        super(reactContext);

        // When sunsetting the old SDK, remove LegacyTransitionWrapper and always use
        // CSQTransitionWrapper
        this.implementation = new LegacyTransitionWrapper(
                reactContext,
                webViewInjector,
                csEventEmitterModuleImpl,
                reactNativeUiThreadUtil);

        this.csqTransitionWrapper = new CSQTransitionWrapper(
                reactContext,
                webViewInjector,
                csEventEmitterModuleImpl,
                reactNativeUiThreadUtil,
                reactNativeViewFinder);
    }

    @NonNull
    @Override
    public String getName() {
        return implementation.getName();
    }

    @ReactMethod
    public void stopTracking() {
        implementation.stopTracking();
    }

    @ReactMethod
    public void setDefaultMasking(boolean isMasked) {
        implementation.setDefaultMasking(isMasked);
    }

    @ReactMethod
    public void resumeTracking() {
        implementation.resumeTracking();
    }

    @ReactMethod
    public void start(boolean isCSQEnabled) {
        if (isCSQEnabled) {
            implementation = csqTransitionWrapper;
        }
        implementation.start();
    }

    @ReactMethod
    public void getUserId(Callback cb) {
        implementation.getUserId(cb);
    }

    @ReactMethod
    public void optIn() {
        implementation.optIn();
    }

    @ReactMethod
    public void optOut() {
        implementation.optOut();
    }

    @ReactMethod
    public void initComponents(@NonNull ReadableMap params) {
        implementation.initComponents(params);
    }

    @ReactMethod
    public void send(String screenView, ReadableArray customVars) {
        implementation.send(screenView, customVars);
    }

    @ReactMethod
    public void sendTransaction(@Nullable String id, double value, double currency) {
        implementation.sendTransaction(id, (float) value, (int) currency);
    }

    @ReactMethod
    public void sendTransactionWithStringCurrency(@Nullable String id, double value, @NonNull String currency) {
        implementation.sendTransactionWithStringCurrency(id, (float) value, currency);
    }

    @ReactMethod
    public void sendDynamicStringVar(@NonNull String key, @NonNull String value) {
        implementation.sendDynamicStringVar(key, value);
    }

    @ReactMethod
    public void sendDynamicIntVar(@NonNull String key, double value) {
        implementation.sendDynamicIntVar(key, (int) value);
    }

    @ReactMethod
    public void sendUserIdentifier(@NonNull final String userIdentifier) {
        implementation.sendUserIdentifier(userIdentifier);
    }

    @ReactMethod
    public void setOnSessionReplayLinkChange() {
        implementation.setOnSessionReplayLinkChange();
    }

    @ReactMethod
    public void handleUrl(@Nullable String urlString) {
        // no-op
    }

    @ReactMethod
    public void injectWebView(final double webViewTag) {
        implementation.injectWebView((int) webViewTag);
    }

    @ReactMethod
    public void removeWebViewInjection(final double webViewTag) {
        implementation.removeWebViewInjection((int) webViewTag);
    }

    @ReactMethod
    public Map<String, Object> getTypedExportedConstants() {
        return implementation.getConstants();
    }

    @ReactMethod
    public void monitorWarn(@NonNull ReadableMap params) {
        implementation.monitorWarn(params);
    }

    @ReactMethod
    public void monitorError(@NonNull ReadableMap params) {
        implementation.monitorError(params);
    }

    @ReactMethod
    public void configureProductAnalytics(@NonNull final String envId, ReadableMap productAnalyticsOptions) {
        implementation = csqTransitionWrapper;
        implementation.configureProductAnalytics(envId, productAnalyticsOptions);
    }

    @ReactMethod
    public void stop() {
        implementation.stop();
    }

    @ReactMethod
    public void pauseTracking() {
        implementation.pauseTracking();
    }

    @ReactMethod
    public void addDynamicNumberVar(@NonNull String key, double value) {
        implementation.addDynamicVar(key, value);
    }

    @ReactMethod
    public void addDynamicStringVar(@NonNull String key, @NonNull String value) {
        implementation.addDynamicVar(key, value);
    }

    @ReactMethod
    public void identify(@NonNull final String identity) {
        implementation.identify(identity);
    }

    @ReactMethod
    public void resetIdentity() {
        implementation.resetIdentity();
    }

    @ReactMethod
    public void trackScreenView(String name, ReadableArray customVars, ReadableMap sourceInfo) {
        implementation.trackScreenView(name, customVars, sourceInfo);
    }

    @ReactMethod
    public void trackTransaction(@Nullable String id, double value, double currency) {
        implementation.trackTransaction(id, (float) value, (int) currency);
    }

    @ReactMethod
    public void trackTransactionWithStringCurrency(@Nullable String id, double value, @NonNull String currency) {
        implementation.trackTransaction(id, (float) value, currency);
    }

    @ReactMethod
    public void trackEvent(@NonNull String event, ReadableMap properties, ReadableMap sourceInfo) {
        implementation.trackEvent(event, properties, sourceInfo);
    }

    @ReactMethod
    public void registerWebView(double webViewTag) {
        implementation.registerWebView((int) webViewTag);
    }

    @ReactMethod
    public void unregisterWebView(double webViewTag) {
        implementation.unregisterWebView((int) webViewTag);
    }

    @ReactMethod
    public void addEventProperties(ReadableMap properties) {
        implementation.addEventProperties(properties);
    }

    @ReactMethod
    public void removeEventProperty(String name) {
        implementation.removeEventProperty(name);
    }

    @ReactMethod
    public void clearEventProperties() {
        implementation.clearEventProperties();
    }

    @ReactMethod
    public void addUserProperties(ReadableMap properties) {
        implementation.addUserProperties(properties);
    }

    @ReactMethod
    public void setUrlMaskingPatterns(ReadableArray patterns) {
        implementation.setUrlMaskingPatterns(patterns);
    }

    @ReactMethod
    public void triggerNativeCrash() {
        implementation.triggerNativeCrash();
    }

    @ReactMethod
    public void setOnMetadataChange() {
        implementation.setOnMetadataChange();
    }
}
