#import "FeedbackReactNativeSdk.h"
#import <PisanoFeedback/PisanoFeedback-Swift.h>
#import <UIKit/UIKit.h>

@implementation FeedbackReactNativeSdk
RCT_EXPORT_MODULE()

+ (BOOL)requiresMainQueueSetup {
    return YES;
}

- (dispatch_queue_t)methodQueue {
    return dispatch_get_main_queue();
}

RCT_EXPORT_METHOD(debugMode:(BOOL)debugMode) {
    [Pisano debugMode:debugMode];
}

#ifdef RCT_NEW_ARCH_ENABLED
RCT_EXPORT_METHOD(boot:(nonnull NSString *)appId
                  accessKey:(nonnull NSString *)accessKey
                  code:(nonnull NSString *)code
                  apiUrl:(nonnull NSString *)apiUrl
                  feedbackUrl:(nonnull NSString *)feedbackUrl
                  eventUrl:(nonnull NSString *)eventUrl
                  callback:(RCTResponseSenderBlock)callback) {
    __block BOOL bootCallbackCalled = NO;
    NSString * _Nullable eventUrlValue = (eventUrl.length > 0) ? eventUrl : nil;
    [Pisano bootWithAppId:appId accessKey:accessKey code:code apiUrl:apiUrl feedbackUrl:feedbackUrl eventUrl:eventUrlValue completion:^(enum CloseStatus status) {
        if (bootCallbackCalled) { return; }
        bootCallbackCalled = YES;
        callback(@[[CloseStatusHelper description:status]]);
    }];
}
#else
RCT_EXPORT_METHOD(boot:(nonnull NSString *)appId
                  accessKey:(nonnull NSString *)accessKey
                  code:(nonnull NSString *)code
                  apiUrl:(nonnull NSString *)apiUrl
                  feedbackUrl:(nonnull NSString *)feedbackUrl
                  eventUrl:(nullable NSString *)eventUrl
                  callback:(RCTResponseSenderBlock)callback) {
    __block BOOL bootCallbackCalled = NO;
    [Pisano bootWithAppId:appId accessKey:accessKey code:code apiUrl:apiUrl feedbackUrl:feedbackUrl eventUrl:eventUrl completion:^(enum CloseStatus status) {
        if (bootCallbackCalled) { return; }
        bootCallbackCalled = YES;
        callback(@[[CloseStatusHelper description:status]]);
    }];
}
#endif

#ifdef RCT_NEW_ARCH_ENABLED
RCT_EXPORT_METHOD(show:(double)viewMode
                  title:(nullable NSString *)title
                  titleFontSize:(nonnull NSNumber *)titleFontSize
                  code:(nullable NSString *)code
                  language:(nullable NSString *)language
                  customer:(nullable NSDictionary *)customer
                  payload:(nullable NSDictionary *)payload
                  callback:(RCTResponseSenderBlock)callback) {
    __block BOOL showCallbackCalled = NO;
    ViewMode mode = (ViewMode)viewMode;
    
    NSMutableDictionary *attrsDictionary = NULL;
    CGFloat titleSize = [titleFontSize floatValue];
    if (titleSize > 0) {
        attrsDictionary = [NSMutableDictionary dictionaryWithObject:[UIFont systemFontOfSize:titleSize]
                                        forKey:NSFontAttributeName];
    }
    
    NSMutableAttributedString *titleAttributedString = NULL;
    if (title != NULL) {
        titleAttributedString = [[NSMutableAttributedString alloc] initWithString:title attributes:attrsDictionary];
    }
    
    [Pisano showWithMode:mode
                   title:titleAttributedString
                language:language
                customer:customer
                 payload:payload
                    code:code
              completion:^(enum CloseStatus status) {
        NSNumber *statusNumber = [NSNumber numberWithInteger:(NSInteger)status];
        if (showCallbackCalled) { return; }
        showCallbackCalled = YES;
        callback(@[statusNumber]);
    }];
}
#else
RCT_EXPORT_METHOD(show:(NSInteger)viewMode
                  title:(nullable NSString *)title
                  titleFontSize:(nullable NSString *)titleFontSize
                  code:(nullable NSString *)code
                  language:(nullable NSString *)language
                  customer:(nullable NSDictionary *)customer
                  payload:(nullable NSDictionary *)payload
                  callback:(RCTResponseSenderBlock)callback) {
    __block BOOL showCallbackCalled = NO;
    ViewMode mode = (ViewMode)viewMode;
    
    NSMutableDictionary *attrsDictionary = NULL;
    if (titleFontSize != NULL) {
        CGFloat titleSize = [titleFontSize floatValue];
        attrsDictionary = [NSMutableDictionary dictionaryWithObject:[UIFont systemFontOfSize:titleSize]
                                        forKey:NSFontAttributeName];
    }
    
    NSMutableAttributedString *titleAttributedString = NULL;
    if (title != NULL) {
        titleAttributedString = [[NSMutableAttributedString alloc] initWithString:title attributes:attrsDictionary];
    }
    
    [Pisano showWithMode:mode
                   title:titleAttributedString
                language:language
                customer:customer
                 payload:payload
                    code:code
              completion:^(enum CloseStatus status) {
        NSNumber *statusNumber = [NSNumber numberWithInteger:(NSInteger)status];
        if (showCallbackCalled) { return; }
        showCallbackCalled = YES;
        callback(@[statusNumber]);
    }];
}
#endif

RCT_EXPORT_METHOD(clear) {
    [Pisano clear];
}

// Don't compile this code when we build for the old architecture.
#ifdef RCT_NEW_ARCH_ENABLED
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params
{
    return std::make_shared<facebook::react::NativeFeedbackReactNativeSdkSpecJSI>(params);
}
#endif

@end
