#import "AppDelegate.h"

#import <React/RCTBundleURLProvider.h>

#import <Firebase/Firebase.h>
#import <objc/runtime.h>
#import <CoreBluetooth/CoreBluetooth.h>

#import <Airbridge/Airbridge.h>
#import <AirbridgeQALibrary/AirbridgeQALibrary.h>
#import <AirbridgeReactNative/AirbridgeReactNative.h>

#import <WebKit/WebKit.h>
#import <AppTrackingTransparency/AppTrackingTransparency.h>

#import "APNsSetting.h"

#import "AirbridgeQA-Swift.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  self.moduleName = @"AirbridgeQA";
  // You can add your custom initial props in the dictionary below.
  // They will be passed down to the ViewController used by React Native.
  self.initialProps = @{};
  
  [FIRApp configure];
  [self swizzleWebViewAlert];
  [AirbridgeJSONSwizzler_Swift swizzleLoadAirbridgeJSON];
  
  // 권한 요청 없이 APNs 등록
  [[UIApplication sharedApplication] registerForRemoteNotifications];
  
  [AirbridgeReactNative initializeSDKWithName:AirbridgeJSONSwizzler_Swift.appName
                                        token:AirbridgeJSONSwizzler_Swift.appToken];

  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  const unsigned char *bytes = (const unsigned char *)[deviceToken bytes];
  NSMutableString* apns = [[NSMutableString alloc] initWithCapacity:deviceToken.length * 2];
  for (int i=0; i<deviceToken.length; i++) {
      [apns appendFormat:@"%02x", bytes[i]];
  }
  [APNsSetting setApns:apns];
  NSLog(@"[app] AppDelegate setApns : %@", apns);
}

- (void)swizzleWebViewAlert {
  SEL selector = NSSelectorFromString(@"webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:");
  Method method = class_getInstanceMethod(NSClassFromString(@"RNCWebViewImpl"), selector);
  Method newMethod = class_getInstanceMethod(self.class, selector);
  IMP newImplmentation = method_getImplementation(newMethod);
  method_setImplementation(method, newImplmentation);
}

- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *))completionHandler{
  UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:prompt preferredStyle:UIAlertControllerStyleAlert];
  [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
    textField.accessibilityIdentifier = @"textField";
    textField.text = defaultText;
  }];
  UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
    completionHandler([[alert.textFields lastObject] text]);
  }];
  okAction.accessibilityIdentifier = @"ok";
  [alert addAction:okAction];
  UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
    completionHandler(nil);
  }];
  cancelAction.accessibilityIdentifier = @"cancel";
  [alert addAction:cancelAction];
  alert.preferredAction = okAction;
  [RCTPresentedViewController() presentViewController:alert animated:YES completion:NULL];
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
  return [self bundleURL];
}

- (NSURL *)bundleURL
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options
{
  [AirbridgeReactNative trackDeeplinkWithUrl:url];
  return YES;
}

-  (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
  restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
  [AirbridgeReactNative trackDeeplinkWithUserActivity:userActivity];
  return YES;
}

- (void) application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)userInfo
    fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler  
  {
    if ([userInfo objectForKey:@"airbridge-uninstall-tracking"] != nil) {
        NSLog(@"(Airbridge) Airbridge silent push notification received");
    } else {
        NSLog(@"(Airbridge) Message data payload: %@", userInfo);
    }
  }

@end
