#import "RNQualtricsDigital.h"
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>

#ifdef RCT_NEW_ARCH_ENABLED
#import "RNRNQualtricsDigitalSpec.h"
#endif

/**
 * Interface for the Swift implementation class.
 */
@interface RNQualtricsDigitalImpl : NSObject

// MARK: - Setup
- (void)setEventEmitter:(RCTEventEmitter *)eventEmitter;

// MARK: - Asynchronous Methods
- (void)initialize:(NSString *)brandId zoneId:(NSString *)zoneId interceptId:(NSString *)interceptId;
- (void)initializeWithCompletion:(NSString *)brandId zoneId:(NSString *)zoneId interceptId:(NSString *)interceptId;
- (void)initializeProject:(NSString *)brandId zoneId:(NSString *)zoneId extRefId:(NSString *)extRefId;
- (void)evaluateTargetingLogic;
- (void)evaluateProject;
- (void)evaluateIntercept:(NSString *)interceptId;
- (void)display:(BOOL)autoCloseSurvey callback:(RCTResponseSenderBlock)callback;
- (void)displayTarget:(NSString *)surveyUrl autoCloseSurvey:(NSNumber *)autoCloseSurvey callback:(RCTResponseSenderBlock)callback;
- (void)displayIntercept:(NSString *)interceptId autoCloseSurvey:(NSNumber *)autoCloseSurvey callback:(RCTResponseSenderBlock)callback;
- (void)getInitializedIntercepts:(RCTResponseSenderBlock)callback;
- (void)getPassingIntercepts:(RCTResponseSenderBlock)callback;
- (void)setString:(NSString *)key value:(NSString *)value;
- (void)setNumber:(NSString *)key value:(double)value;
- (void)setDateTime:(NSString *)key;
- (void)setLastDisplayTimeForIntercept:(NSString *)interceptId;
- (void)setNotificationIconAsset:(NSString *)asset;
- (void)registerViewVisit:(NSString *)viewName;
- (void)resetTimer;
- (void)resetViewCounter;
- (void)recordClick;
- (void)recordImpression;

@end

@interface RNQualtricsDigital () <RCTBridgeModule>
@end

@implementation RNQualtricsDigital {
    RNQualtricsDigitalImpl *_swiftImpl;
}

RCT_EXPORT_MODULE()

/**
 * Initialize module with main thread and avoid lazy loading.
 * We want to initialize module before UI so we can display intercepts.
 * https://github.com/facebook/react-native/blob/main/packages/react-native/React/Base/RCTBridgeModule.h#L315-L326
 */
+ (BOOL)requiresMainQueueSetup {
    return YES;
}

- (instancetype)init {
    if (self = [super init]) {
        _swiftImpl = [RNQualtricsDigitalImpl new];
        [_swiftImpl setEventEmitter:self];
    }
    return self;
}

/**
 * Forces SDK to execute all methods on the main thread by default.
 * Displaying UI thing needs main thread.
 * https://reactnative.dev/docs/next/legacy/native-modules-ios#threading
 */
- (dispatch_queue_t)methodQueue {
    return dispatch_get_main_queue();
}

- (NSArray<NSString *> *)supportedEvents {
    return @[
        @"initializeEvent",
        @"evaluateEvent",
        @"initializeProjectEvent",
        @"evaluateProjectEvent",
        @"evaluateInterceptEvent"
    ];
}

#pragma mark - Asynchronous Methods

RCT_EXPORT_METHOD(initialize:(NSString *)brandId
                  zoneId:(NSString *)zoneId
                  interceptId:(NSString *)interceptId)
{
    [_swiftImpl initialize:brandId zoneId:zoneId interceptId:interceptId];
}

RCT_EXPORT_METHOD(initializeWithCompletion:(NSString *)brandId
                  zoneId:(NSString *)zoneId
                  interceptId:(NSString *)interceptId)
{
    [_swiftImpl initializeWithCompletion:brandId zoneId:zoneId interceptId:interceptId];
}

RCT_EXPORT_METHOD(initializeProject:(NSString *)brandId
                  zoneId:(NSString *)zoneId
                  extRefId:(NSString *)extRefId)
{
    [_swiftImpl initializeProject:brandId zoneId:zoneId extRefId:extRefId];
}

RCT_EXPORT_METHOD(evaluateTargetingLogic)
{
    [_swiftImpl evaluateTargetingLogic];
}

RCT_EXPORT_METHOD(evaluateProject)
{
    [_swiftImpl evaluateProject];
}

RCT_EXPORT_METHOD(evaluateIntercept:(NSString *)interceptId)
{
    [_swiftImpl evaluateIntercept:interceptId];
}

RCT_EXPORT_METHOD(display:(BOOL)autoCloseSurvey
                  callback:(RCTResponseSenderBlock)callback)
{
    [_swiftImpl display:autoCloseSurvey callback:callback];
}

RCT_EXPORT_METHOD(displayTarget:(NSString *)surveyUrl
                  autoCloseSurvey:(NSNumber *)autoCloseSurvey
                  callback:(RCTResponseSenderBlock)callback)
{
    [_swiftImpl displayTarget:surveyUrl autoCloseSurvey:autoCloseSurvey callback:callback];
}

RCT_EXPORT_METHOD(displayIntercept:(NSString *)interceptId
                  autoCloseSurvey:(NSNumber *)autoCloseSurvey
                  callback:(RCTResponseSenderBlock)callback)
{
    [_swiftImpl displayIntercept:interceptId autoCloseSurvey:autoCloseSurvey callback:callback];
}

RCT_EXPORT_METHOD(getInitializedIntercepts:(RCTResponseSenderBlock)callback)
{
    [_swiftImpl getInitializedIntercepts:callback];
}

RCT_EXPORT_METHOD(getPassingIntercepts:(RCTResponseSenderBlock)callback)
{
    [_swiftImpl getPassingIntercepts:callback];
}

RCT_EXPORT_METHOD(setString:(NSString *)key
                  value:(NSString *)value)
{
    [_swiftImpl setString:key value:value];
}

RCT_EXPORT_METHOD(setNumber:(NSString *)key
                  value:(double)value)
{
    [_swiftImpl setNumber:key value:value];
}

RCT_EXPORT_METHOD(setDateTime:(NSString *)key)
{
    [_swiftImpl setDateTime:key];
}

RCT_EXPORT_METHOD(setLastDisplayTimeForIntercept:(NSString *)interceptId)
{
    [_swiftImpl setLastDisplayTimeForIntercept:interceptId];
}

RCT_EXPORT_METHOD(setNotificationIconAsset:(NSString *)asset)
{
    [_swiftImpl setNotificationIconAsset:asset];
}

RCT_EXPORT_METHOD(registerViewVisit:(NSString *)viewName)
{
    [_swiftImpl registerViewVisit:viewName];
}

RCT_EXPORT_METHOD(resetTimer)
{
    [_swiftImpl resetTimer];
}

RCT_EXPORT_METHOD(resetViewCounter)
{
    [_swiftImpl resetViewCounter];
}

RCT_EXPORT_METHOD(recordClick)
{
    [_swiftImpl recordClick];
}

RCT_EXPORT_METHOD(recordImpression)
{
    [_swiftImpl recordImpression];
}

#ifdef RCT_NEW_ARCH_ENABLED
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
    (const facebook::react::ObjCTurboModule::InitParams &)params
{
    return std::make_shared<facebook::react::NativeRNQualtricsDigitalSpecJSI>(params);
}
#endif

@end
