package com.contentsquare.rn;

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

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.Callback;
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.ReadableMap;

import java.util.Map;

public class ContentsquareModule extends ReactContextBaseJavaModule {

    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();
    }

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

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

    @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 setDefaultMasking(Boolean isMasked) {
        implementation.setDefaultMasking(isMasked);
    }

    @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, float value, int currency) {
        implementation.sendTransaction(id, value, currency);
    }

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

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

    @ReactMethod
    public void sendDynamicIntVar(@NonNull String key, int value) {
        implementation.sendDynamicIntVar(key, 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 int webViewTag) {
        implementation.injectWebView(webViewTag);
    }

    @ReactMethod
    public void removeWebViewInjection(final int webViewTag) {
        implementation.removeWebViewInjection(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, float value, int currency) {
        implementation.trackTransaction(id, value, currency);
    }

    @ReactMethod
    public void trackTransactionWithStringCurrency(@Nullable String id, float value, @NonNull String currency) {
        implementation.trackTransaction(id, 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();
    }
}
