#import "SmartechNudges.h"
#import <React/RCTLog.h>
#import <React/RCTConvert.h>
#import <SmartechNudges/Hansel.h>
#import <SmartechNudges/HanselUser.h>
#import <SmartechNudges/HanselTracker.h>

#ifdef RCT_NEW_ARCH_ENABLED
#import <NativeSmartechNudgesSpec/NativeSmartechNudgesSpec.h>
#endif

// Import existing implementations
#import "HanselRn.h"
#import "HanselUserRn.h"
#import "HanselConfigsRn.h"
#import "HanselTrackerRn.h"
#import "HanselRnUtils.h"

@implementation SmartechNudges {
    // Delegate to existing modules
    HanselRn *_hanselRn;
    HanselUserRn *_hanselUserRn;
    HanselConfigsRn *_hanselConfigsRn;
    HanselTrackerRn *_hanselTrackerRn;
}

RCT_EXPORT_MODULE()

- (instancetype)init {
    self = [super init];
    if (self) {
        // Initialize delegate modules
        _hanselRn = [[HanselRn alloc] init];
        _hanselUserRn = [[HanselUserRn alloc] init];
        _hanselConfigsRn = [[HanselConfigsRn alloc] init];
        _hanselTrackerRn = [[HanselTrackerRn alloc] init];
    }
    return self;
}

#pragma mark - Event Emitter Support

- (NSArray<NSString *> *)supportedEvents {
    return @[@"HanselInternalEvent", @"HanselActionPerformed", @"HanselDeepLinkListener"];
}

#pragma mark - HanselRn Methods

RCT_EXPORT_METHOD(getInteractionMaps:(RCTResponseSenderBlock)callback) {
    [_hanselRn getInteractionMaps:callback];
}

RCT_EXPORT_METHOD(onBackButtonPressed:(RCTResponseSenderBlock)callback) {
    [_hanselRn onBackButtonPressed:callback];
}

RCT_EXPORT_METHOD(onSetScreen:(NSString *)screenName) {
    [_hanselRn onSetScreen:screenName];
}

RCT_EXPORT_METHOD(onUnsetScreen) {
    [_hanselRn onUnsetScreen];
}

RCT_EXPORT_METHOD(setNativeID) {
    [_hanselRn setNativeID];
}

RCT_EXPORT_METHOD(showToast:(NSString *)text longDuration:(BOOL)longDuration) {
    // iOS doesn't have native toast, so we'll log it
    RCTLogInfo(@"[Hansel Toast] %@", text);
}

RCT_EXPORT_METHOD(setTypeface:(NSString *)fontFileName) {
    // iOS implementation would be different, placeholder for now
    RCTLogInfo(@"[Hansel setTypeface] %@", fontFileName);
}

RCT_EXPORT_METHOD(setAppFont:(NSString *)fontName) {
    [_hanselRn setAppFont:fontName];
}

#pragma mark - HanselUser Methods

RCT_EXPORT_METHOD(putStringAttribute:(NSString *)key value:(NSString *)value) {
    [_hanselUserRn putStringAttribute:key value:value];
}

RCT_EXPORT_METHOD(putDoubleAttribute:(NSString *)key value:(double)value) {
    [_hanselUserRn putDoubleAttribute:key value:value];
}

RCT_EXPORT_METHOD(putBooleanAttribute:(NSString *)key value:(BOOL)value) {
    [_hanselUserRn putBooleanAttribute:key value:value];
}

RCT_EXPORT_METHOD(putPrivateStringAttribute:(NSString *)key value:(NSString *)value) {
    [_hanselUserRn putPrivateStringAttribute:key value:value];
}

RCT_EXPORT_METHOD(putPrivateDoubleAttribute:(NSString *)key value:(double)value) {
    [_hanselUserRn putPrivateDoubleAttribute:key value:value];
}

RCT_EXPORT_METHOD(putPrivateBooleanAttribute:(NSString *)key value:(BOOL)value) {
    [_hanselUserRn putPrivateBooleanAttribute:key value:value];
}

RCT_EXPORT_METHOD(setUserId:(NSString *)userId) {
    [_hanselUserRn setUserId:userId];
}

RCT_EXPORT_METHOD(clearAttribute:(NSString *)key) {
    [_hanselUserRn clearAttribute:key];
}

RCT_EXPORT_METHOD(clear) {
    [_hanselUserRn clear];
}

#pragma mark - HanselConfigs Methods

RCT_EXPORT_METHOD(getString:(NSString *)configName fallbackValue:(NSString *)fallbackValue callback:(RCTResponseSenderBlock)callback) {
    [_hanselConfigsRn getString:configName fallbackValue:fallbackValue callback:callback];
}

RCT_EXPORT_METHOD(getBoolean:(NSString *)configName fallbackValue:(BOOL)fallbackValue callback:(RCTResponseSenderBlock)callback) {
    [_hanselConfigsRn getBoolean:configName fallbackValue:fallbackValue callback:callback];
}

RCT_EXPORT_METHOD(getDouble:(NSString *)configName fallbackValue:(double)fallbackValue callback:(RCTResponseSenderBlock)callback) {
    [_hanselConfigsRn getDouble:configName fallbackValue:fallbackValue callback:callback];
}

RCT_EXPORT_METHOD(getList:(NSString *)configName defaultValue:(NSArray *)defaultValue callback:(RCTResponseSenderBlock)callback) {
    [_hanselConfigsRn getList:configName defaultValue:defaultValue callback:callback];
}

RCT_EXPORT_METHOD(getJSONArray:(NSString *)configName defaultValue:(NSArray *)defaultValue callback:(RCTResponseSenderBlock)callback) {
    [_hanselConfigsRn getJSONArray:configName defaultValue:defaultValue callback:callback];
}

RCT_EXPORT_METHOD(getJSONObject:(NSString *)configName defaultValue:(NSDictionary *)defaultValue callback:(RCTResponseSenderBlock)callback) {
    [_hanselConfigsRn getJSONObject:configName defaultValue:defaultValue callback:callback];
}

#pragma mark - HanselTracker Methods

RCT_EXPORT_METHOD(logEvent:(NSString *)eventName vendor:(NSString *)vendor hanselProperties:(NSDictionary *)hanselProperties callback:(RCTResponseSenderBlock)callback) {
    [_hanselTrackerRn logEvent:eventName vendor:vendor hanselProperties:hanselProperties callback:callback];
}

RCT_EXPORT_METHOD(getHanselData:(NSString *)eventName andVendor:(NSString *)vendor withProperties:(NSDictionary *)properties callback:(RCTResponseSenderBlock)callback) {
    [_hanselTrackerRn getHanselData:eventName andVendor:vendor withProperties:properties callback:callback];
}

RCT_EXPORT_METHOD(isUsedInMap:(NSString *)event andVendor:(NSString *)vendor withProperties:(NSDictionary *)properties callback:(RCTResponseSenderBlock)callback) {
    [_hanselTrackerRn isUsedInMap:event andVendor:vendor withProperties:properties callback:callback];
}

RCT_EXPORT_METHOD(registerHanselTrackerListener) {
    [_hanselTrackerRn registerHanselTrackerListener];
}

RCT_EXPORT_METHOD(registerHanselActionListenerWithActionName:(NSString *)actionName) {
    [_hanselTrackerRn registerHanselActionListenerWithActionName:actionName];
}

RCT_EXPORT_METHOD(registerHanselDeeplinkListener) {
    [_hanselTrackerRn registerHanselDeeplinkListener];
}

RCT_EXPORT_METHOD(deRegisterListener) {
    [_hanselTrackerRn deRegisterListener];
}

RCT_EXPORT_METHOD(removeHanselActionListenerForAction:(NSString *)actionName) {
    [_hanselTrackerRn removeHanselActionListenerForAction:actionName];
}

#pragma mark - HanselLogs Methods

RCT_EXPORT_METHOD(e:(NSString *)tag message:(NSString *)message) {
    NSLog(@"[%@] %@", tag, message);
}


#pragma mark - Helper Methods

+ (BOOL)requiresMainQueueSetup {
    return NO;
}

- (NSDictionary *)constantsToExport {
    return @{};
}

- (NSDictionary *)getConstants {
    return @{};
}

#pragma mark - Observer

- (void)startObserving {
    @try {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sendEvent:) name:FIRE_EVENT_NOTIFICATION object:nil];
    } @catch (NSException *exception) {
        NSLog(@"Hansel error: Exception caught in startObserving method in HanselRn bridge.");
    }
}

- (void)stopObserving {
    @try {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    } @catch (NSException *exception) {
        NSLog(@"Hansel error: Exception caught in stopObserving method in HanselRn bridge.");
    }
}

- (void)sendEvent: (NSNotification*) notification {
    @try {
       // if(hasListeners) {
            NSDictionary* userInfo = notification.userInfo;
            [self sendEventWithName:userInfo[NOTIFICATION_EVENT_NAME] body:userInfo[NOTIFICATION_BODY]];
      //  }
        
    } @catch (NSException *exception) {
        NSLog(@"Hansel error: Exception caught in sendEvent method in HanselRn bridge.");
    }
}


#pragma mark - TurboModule Support

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

@end
