package com.contentsquare.rn;

import android.util.Log;

import androidx.annotation.Nullable;

import com.contentsquare.rn.csq.masking.CSQMaskingPackage;
import com.contentsquare.rn.erroranalysis.ErrorAnalysisModuleImpl;
import com.contentsquare.rn.eventEmitter.CSEventEmitterModuleImpl;
import com.contentsquare.rn.masking.CSMaskingPackage;
import com.contentsquare.rn.utils.ReactNativeUiThreadUtil;
import com.contentsquare.rn.utils.ReactNativeViewFinder;
import com.contentsquare.rn.webview.WebViewInjector;
import com.facebook.react.TurboReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.module.model.ReactModuleInfo;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import com.facebook.react.uimanager.ViewManager;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;

public class ContentsquareModulePackage extends TurboReactPackage {

    private CSEventEmitterModuleImpl csEventEmitterModuleImpl;
    private CSMaskingPackage csMaskingPackage;
    private CSQMaskingPackage csqMaskingPackage;

    @Nullable
    @Override
    public NativeModule getModule(String name, ReactApplicationContext reactContext) {
        if (csEventEmitterModuleImpl == null) {
            csEventEmitterModuleImpl = new CSEventEmitterModuleImpl(reactContext);
        }
        ReactNativeUiThreadUtil reactNativeUiThreadUtil = new ReactNativeUiThreadUtil();
        ReactNativeViewFinder reactNativeViewFinder = new ReactNativeViewFinder(reactNativeUiThreadUtil);
        WebViewInjector webViewInjector = new WebViewInjector(reactNativeViewFinder,
                new WebViewInjector.SDKWebViewManager());

        return switch (name) {
            case ContentsquareModuleImpl.NAME ->
                    new ContentsquareModule(reactContext, webViewInjector, csEventEmitterModuleImpl,
                            reactNativeUiThreadUtil, reactNativeViewFinder);
            case ErrorAnalysisModuleImpl.NAME -> new ErrorAnalysisModule(reactContext);
            case CSEventEmitterModuleImpl.NAME ->
                    new CSEventEmitterModule(reactContext, csEventEmitterModuleImpl);
            case HeapReactNativeBridgeModule.NAME ->
                    new HeapReactNativeBridgeModule(reactContext);
            default -> null;
        };

    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        if (csMaskingPackage == null) {
            csMaskingPackage = new CSMaskingPackage();
        }

        if (csqMaskingPackage == null) {
            csqMaskingPackage = new CSQMaskingPackage();
        }

        List<ViewManager> viewManagers = new ArrayList<>(
                csMaskingPackage.createViewManagers(reactContext)
        );

        viewManagers.addAll(csqMaskingPackage.createViewManagers(reactContext));

        return viewManagers;
    }

    @Override
    public ReactModuleInfoProvider getReactModuleInfoProvider() {
        return () -> {
            final Map<String, ReactModuleInfo> moduleInfos = new HashMap<>();
            boolean isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
            moduleInfos.put(
                    ContentsquareModuleImpl.NAME,
                    new ReactModuleInfo(
                            ContentsquareModuleImpl.NAME,
                            ContentsquareModuleImpl.NAME,
                            false, // canOverrideExistingModule
                            false, // needsEagerInit
                            true, // hasConstants
                            false, // isCxxModule
                            isTurboModule // isTurboModule
                    ));
            moduleInfos.put(
                    ErrorAnalysisModuleImpl.NAME,
                    new ReactModuleInfo(
                            ErrorAnalysisModuleImpl.NAME,
                            ErrorAnalysisModuleImpl.NAME,
                            false, // canOverrideExistingModule
                            false, // needsEagerInit
                            false, // hasConstants
                            false, // isCxxModule
                            isTurboModule // isTurboModule
                    ));
            moduleInfos.put(
                    CSEventEmitterModuleImpl.NAME,
                    new ReactModuleInfo(
                            CSEventEmitterModuleImpl.NAME,
                            CSEventEmitterModuleImpl.NAME,
                            false, // canOverrideExistingModule
                            false, // needsEagerInit
                            false, // hasConstants
                            false, // isCxxModule
                            isTurboModule // isTurboModule
                    ));
            moduleInfos.put(
                    HeapReactNativeBridgeModule.NAME,
                    new ReactModuleInfo(
                            HeapReactNativeBridgeModule.NAME,
                            HeapReactNativeBridgeModule.NAME,
                            false, // canOverrideExistingModule
                            false, // needsEagerInit
                            false, // hasConstants
                            false, // isCxxModule
                            isTurboModule // isTurboModule
                    ));
            return moduleInfos;
        };
    }
}
