#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

/**
* Downstream event receiver protocol. Implemented by ATReactNativeBridge,
* EventEmitter forwards to RCTDeviceEventEmitter through sink,
* Avoid EventEmitter.m directly importing RNATBridgeSpec.h containing C++.
 */
@protocol ATReactNativeEventSink <NSObject>
- (void)emitEventName:(NSString *)name body:(nullable id)body;
@end

/**
* Native → JS only event channel (corresponding to Flutter `ATSendSignalManager` / Android `ATReactNativeEventEmitter`).
 *
* The 5 Delegate on the business side pass [SendEventManager sendMethod:arguments:result:]
* (ATSendSignalManager gasket) is adjusted here, and then pressed by this category 8 callName + unified payload structure
* Transfer to sink (i.e. ATReactNativeBridge), and finally pass RCTCallableJSModules.invokeModule
* Call JS side RCTDeviceEventEmitter.emit, received by NativeEventEmitter subscribers.
 *
* 🔴 Thread life gate: The native callback may be in a sub-thread, and you must switch back to the main thread and then emit (RN 0.85 strictly requires the main thread).
 */
@interface ATReactNativeEventEmitter : NSObject

+ (instancetype)sharedInstance;

/** Called by ATReactNativeBridge in init via setSink:self to register as downstream channel. */
- (void)setSink:(nullable id<ATReactNativeEventSink>)sink;

/** Send callback to JS (8 callName + unified payload). Always on main thread. */
- (void)sendCallbackWithCallName:(NSString *)callName
                    callbackName:(NSString *)callbackName
                     placementID:(nullable NSString *)placementID
                        extraDic:(nullable NSDictionary *)extraDic
                  requestMessage:(nullable NSString *)requestMessage;

@end

NS_ASSUME_NONNULL_END
