//
//  WEInboxReact.mm
//  WebEngage Inbox React Native Module Implementation
//

#import "WEInboxReact.h"

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

#import "react_native_webengage_inbox-Swift.h"

#define SAFE_EXECUTE(code) \
  do { \
    if (!self.inboxImpl) { \
      NSLog(@"[WEInboxReact] Inbox not initialized in %s", __func__); \
      return; \
    } \
    @try { code } \
    @catch (NSException *e) { \
      NSLog(@"[WEInboxReact] Error in %s: %@", __func__, e.reason); \
    } \
  } while(0)

#define SAFE_EXECUTE_WITH_CALLBACK(code, callback) \
  do { \
    if (!callback) { \
      NSLog(@"[WEInboxReact] Callback is nil in %s", __func__); \
      return; \
    } \
    if (!self.inboxImpl) { \
      NSLog(@"[WEInboxReact] Inbox not initialized in %s", __func__); \
      callback(@[[NSNull null], @{@"error": @"Inbox not initialized"}]); \
      return; \
    } \
    @try { code } \
    @catch (NSException *e) { \
      NSLog(@"[WEInboxReact] Error in %s: %@", __func__, e.reason); \
      callback(@[[NSNull null], @{@"error": e.reason ?: @"Unknown error"}]); \
    } \
  } while(0)

#define SAFE_EXECUTE_WITH_PARAM(code, param, paramName) \
  do { \
    if (!self.inboxImpl) { \
      NSLog(@"[WEInboxReact] Inbox not initialized in %s", __func__); \
      return; \
    } \
    if (!param) { \
      NSLog(@"[WEInboxReact] %s is nil in %s", paramName, __func__); \
      return; \
    } \
    @try { code } \
    @catch (NSException *e) { \
      NSLog(@"[WEInboxReact] Error in %s: %@", __func__, e.reason); \
    } \
  } while(0)

@interface WEInboxReact () <WENotificationInboxDelegate>
@property (nonatomic, strong) WENotificationInboxImpl *inboxImpl;
@end

@implementation WEInboxReact

- (instancetype)init {
  self = [super init];
  if (self) {
    _inboxImpl = [[WENotificationInboxImpl alloc] init];
    _inboxImpl.delegate = self;
  }
  return self;
}

- (void)dealloc {
  _inboxImpl.delegate = nil;
}

RCT_EXPORT_MODULE()

+ (BOOL)requiresMainQueueSetup {
  return YES;
}

RCT_EXPORT_METHOD(initWENotificationInbox) {
  SAFE_EXECUTE([self.inboxImpl initWENotificationInbox];);
}

RCT_EXPORT_METHOD(onNotificationIconClick) {
  SAFE_EXECUTE([self.inboxImpl onNotificationIconClick];);
}

RCT_EXPORT_METHOD(getNotificationCount:(RCTResponseSenderBlock)callback) {
  SAFE_EXECUTE_WITH_CALLBACK([self.inboxImpl getNotificationCount:callback];, callback);
}

RCT_EXPORT_METHOD(getNotificationList:(NSString *)offset callback:(RCTResponseSenderBlock)callback) {
  SAFE_EXECUTE_WITH_CALLBACK([self.inboxImpl getNotificationList:offset callback:callback];, callback);
}

RCT_EXPORT_METHOD(markRead:(NSDictionary *)readMap) {
  SAFE_EXECUTE_WITH_PARAM([self.inboxImpl markRead:readMap];, readMap, "readMap");
}

RCT_EXPORT_METHOD(markUnread:(NSDictionary *)readMap) {
  SAFE_EXECUTE_WITH_PARAM([self.inboxImpl markUnread:readMap];, readMap, "readMap");
}

RCT_EXPORT_METHOD(markDelete:(NSDictionary *)readMap) {
  SAFE_EXECUTE_WITH_PARAM([self.inboxImpl markDelete:readMap];, readMap, "readMap");
}

RCT_EXPORT_METHOD(trackClick:(NSDictionary *)readMap) {
  SAFE_EXECUTE_WITH_PARAM([self.inboxImpl trackClick:readMap];, readMap, "readMap");
}

RCT_EXPORT_METHOD(trackView:(NSDictionary *)readMap) {
  SAFE_EXECUTE_WITH_PARAM([self.inboxImpl trackView:readMap];, readMap, "readMap");
}

RCT_EXPORT_METHOD(readAll:(NSArray *)notificationList) {
  SAFE_EXECUTE_WITH_PARAM([self.inboxImpl readAll:notificationList];, notificationList, "notificationList");
}

RCT_EXPORT_METHOD(unReadAll:(NSArray *)notificationList) {
  SAFE_EXECUTE_WITH_PARAM([self.inboxImpl unReadAll:notificationList];, notificationList, "notificationList");
}

RCT_EXPORT_METHOD(deleteAll:(NSArray *)notificationList) {
  SAFE_EXECUTE_WITH_PARAM([self.inboxImpl deleteAll:notificationList];, notificationList, "notificationList");
}

#ifdef RCT_NEW_ARCH_ENABLED
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
    (const facebook::react::ObjCTurboModule::InitParams &)params {
  @try {
    return std::make_shared<facebook::react::NativeWEInboxModuleSpecJSI>(params);
  } @catch (NSException *exception) {
    NSLog(@"[WEInboxReact] Error creating TurboModule: %@", exception.reason);
    return nullptr;
  }
}
#endif

- (NSArray<NSString *> *)supportedEvents {
  @try {
    return [WENotificationInboxImpl supportedEvents];
  } @catch (NSException *exception) {
    NSLog(@"[WEInboxReact] Error getting supported events: %@", exception.reason);
    return @[];
  }
}

- (void)sendEventWithName:(NSString *)name result:(NSDictionary *)result {
  if (!name) {
    NSLog(@"[WEInboxReact] Event name is nil");
    return;
  }
  @try {
    [self sendEventWithName:name body:result];
  } @catch (NSException *exception) {
    NSLog(@"[WEInboxReact] Error sending event %@: %@", name, exception.reason);
  }
}

@end
