#import "ATReactNativeEventEmitter.h"
#import "ATConfiguration.h"

@interface ATReactNativeEventEmitter ()
@property (nonatomic, weak) id<ATReactNativeEventSink> sink;
@end

@implementation ATReactNativeEventEmitter

+ (instancetype)sharedInstance {
    static ATReactNativeEventEmitter *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[ATReactNativeEventEmitter alloc] init];
    });
    return instance;
}

- (void)setSink:(id<ATReactNativeEventSink>)sink {
    _sink = sink;
}

- (void)sendCallbackWithCallName:(NSString *)callName
                    callbackName:(NSString *)callbackName
                     placementID:(NSString *)placementID
                        extraDic:(NSDictionary *)extraDic
                  requestMessage:(NSString *)requestMessage {

    NSMutableDictionary *payload = [NSMutableDictionary dictionary];
    payload[@"callbackName"]    = callbackName ?: @"";
    payload[@"placementID"]     = placementID  ?: @"";
    payload[@"extraDic"]        = extraDic     ?: @{};
    payload[@"requestMessage"]  = requestMessage ?: @"";

    __weak id<ATReactNativeEventSink> sink = self.sink;
    NSString *name = callName ?: @"";

    void (^emit)(void) = ^{
        id<ATReactNativeEventSink> strongSink = sink;
        if (strongSink == nil) {
// The bridge has not been built yet (the JS bundle has not been loaded) or has been destroyed; discard the event instead of crashing.
            ATLog(@"[ATRNBridge] sink not ready, drop event=%@/%@ placementID=%@",
                  name, payload[@"callbackName"], payload[@"placementID"]);
            return;
        }
      ATLog(@"[ATRNBridge] sendevent=%@/%@ placementID=%@",
            name, payload[@"callbackName"], payload[@"placementID"]);
        [strongSink emitEventName:name body:payload];
    };

// 🔴 Thread life gate: the native callback may be in a sub-thread and must be switched back to the main thread
    if ([NSThread isMainThread]) {
        emit();
    } else {
        dispatch_async(dispatch_get_main_queue(), emit);
    }
}

@end
