#import <string>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <PokktSDK/PokktSDK.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
#import <React/RCTBridgeModule.h>


#pragma mark - CONSTS: Framework-to-Pokkt Operations

#define     SET_POKKT_CONFIG                @"setPokktConfig"
#define     SET_THIRDPARTY_ID               @"setThirdPartyUserId"
#define     SET_AD_PLAYER_VIEW_CONFIG       @"setAdPlayerViewConfig"
#define     SET_USER_DETAILS                @"setUserDetails"
#define     SET_CALLBACK_EXTRA_PARAMS       @"setCallbackExtraParams"

#define     CACHE_AD                        @"cacheAd"
#define     SHOW_AD                         @"showAd"

#define     BANNER_DESTROY                  @"destroyBanner"

#define     DEBUGGING_SHOULD_DEBUG          @"Debugging_shouldDebug"
#define     DEBUGGING_SHOW_TOAST            @"Debugging_showToast"
#define     DEBUGGING_SHOW_LOG              @"Debugging_showLog"

#define     SET_DATA_ACCESS_CONSENT         @"setDataAccessConsent"


#pragma mark - CONSTS: Pokkt-to-Framework Events

// Video Ad Related Events
#define EVENT_AD_CACHING_RESULT             @"AdCachingResult"
#define EVENT_AD_DISPLAYED_RESULT           @"AdDisplayedResult"
#define EVENT_AD_CLOSED                     @"AdClosed"
#define EVENT_AD_CLICKED                    @"AdClicked"
#define EVENT_AD_GRATIFIED                  @"AdGratified"

// Banner Ad Delegate
#define EVENT_BANNER_EXPANDED               @"BannerExpanded"
#define EVENT_BANNER_RESIZED                @"BannerResized"
#define EVENT_BANNER_COLLAPSED              @"BannerCollapsed"

// banner related
#define TOP_LEFT        1
#define TOP_CENTER      2
#define TOP_RIGHT       3
#define MIDDLE_LEFT     4
#define MIDDLE_CENTER   5
#define MIDDLE_RIGHT    6
#define BOTTOM_LEFT     7
#define BOTTOM_CENTER   8
#define BOTTOM_RIGHT    9

#define BOOL_TO_STRING(value) (value ? @"true" : @"false")


#pragma mark - Utils & Definitions

// utils
void notifyFramework(NSString *operation, NSString *param);
UIViewController* getRootViewController();
NSDictionary* extractJSON(NSString* jsonString);
PokktAdPlayerViewConfig* getAdPlayerViewConfigFromJSONString(NSString* configString);
PokktUserInfo* getUserDetailsFromJSONString(NSString* stringData);
PokktConsentInfo* getConsentInfoFromJSONString(NSString* stringData);
NSString* stringifyJSONDictionary(NSDictionary *jsonObject);


// banner-util methods
void topLeft(UIView * view);
void topRight(UIView * view);
void topCenter(UIView * view);
void middleLeft(UIView* view);
void middleRight(UIView * view);
void middleCenter(UIView * view);
void bottomLeft(UIView * view);
void bottomRight(UIView * view);
void bottomCenter(UIView * view);


#pragma mark - ADAPTER

static PokktBannerView* bannerContainer;
static NSDictionary *operations = nil;

static BOOL delegateAssigned = false;

@interface PokktAdsAdapter : NSObject<PokktAdDelegate,PokktBannerAdDelegate>

+ (void) processForOperation:(NSString*)operation withParams:(NSString*)params;

@end

static PokktAdsAdapter *adapter;

#pragma mark - POKKT-TO-FRAMEWORK

@interface PokktPluginEvent : RCTEventEmitter <RCTBridgeModule>
@end

PokktPluginEvent *pokktPluginEvent;

@implementation PokktPluginEvent
RCT_EXPORT_MODULE();

- (NSArray<NSString *> *)supportedEvents
{
    pokktPluginEvent = self;
    return @[@"AdCachingResult",
             @"AdDisplayedResult",
             @"AdClosed",
             @"AdClicked",
             @"AdGratified",
             @"BannerExpanded",
             @"BannerResized",
             @"BannerCollapsed"];
}
@end

void notifyFramework(NSString *operation, NSString *param)
{
    [pokktPluginEvent sendEventWithName:operation body:param];
}


#pragma mark - NATIVE EXTENSIONS
// these are exposed to the framework
// frameworks will call these to communicate

void notifyNative(NSString *operation, NSString *params)
{
    NSLog(@"[POKKT-OBJC] notifyNative of operation: %@ with params: %@", operation, params);
    
    dispatch_sync(dispatch_get_main_queue(), ^{
        [PokktAdsAdapter processForOperation:operation withParams:params];
    });
    
    if (!delegateAssigned) {
        adapter = [[PokktAdsAdapter alloc] init];
        delegateAssigned = true;
    }
}

void notifyNative(const char *operation, const char *params)
{
    NSString *op = [NSString stringWithUTF8String:(operation)];
    NSString *prm = [NSString stringWithUTF8String:(params)];
    notifyNative(op, prm);
}


#pragma mark - ADAPTER: implementation

@implementation PokktAdsAdapter

+ (void)processForOperation:(NSString *)operation withParams:(NSString *)params
{
  // Common APIs
  if ([SET_POKKT_CONFIG isEqualToString:operation]) {
    NSDictionary *jsonObject = extractJSON(params);
    NSString *appId = jsonObject[@"appId"];
    NSString *securityKey = jsonObject[@"securityKey"];
    [PokktAds setPokktConfigWithAppId:appId securityKey:securityKey];
    return;
  }
  
  if ([SET_THIRDPARTY_ID isEqualToString:operation]) {
    [PokktAds setThirdPartyUserId:params];
    return;
  }
  
  if ([SET_AD_PLAYER_VIEW_CONFIG isEqualToString:operation]) {
    [PokktAds setPokktAdPlayerViewConfig:getAdPlayerViewConfigFromJSONString(params)];
    return;
  }
  
  if ([SET_USER_DETAILS isEqualToString:operation]) {
    [PokktAds setUserDetails:getUserDetailsFromJSONString(params)];
    return;
  }
  
  if ([SET_CALLBACK_EXTRA_PARAMS isEqualToString:operation]) {
    NSDictionary *paramDict = extractJSON(params);
    [PokktAds setCallbackExtraParam:paramDict];
    return;
  }
  
  
  // Pokkt Ads APIs
  if ([CACHE_AD isEqualToString:operation]) {
    [PokktAds cacheAd:params withDelegate:adapter];
    return;
  }
  
  if ([SHOW_AD isEqualToString:operation]) {
    
    NSDictionary *jsonObject = extractJSON(params);
    
    NSString* screenId = jsonObject[@"screenId"];
    
    //load banner with given position
    if([jsonObject objectForKey:@"bannerPosition"] != nil) {
      int position = [jsonObject[@"bannerPosition"] intValue];
      
      if (bannerContainer != NULL)
      {
        [PokktAds destroyBanner:bannerContainer];
        bannerContainer = NULL;
      }
      
      bannerContainer = [[PokktBannerView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
      bannerContainer.translatesAutoresizingMaskIntoConstraints = NO;
      
      [getRootViewController().view addSubview:bannerContainer];
      
      switch (position)
      {
        case 1: topLeft(bannerContainer);       break;
        case 2: topCenter(bannerContainer);     break;
        case 3: topRight(bannerContainer);      break;
        case 4: middleLeft(bannerContainer);    break;
        case 5: middleCenter(bannerContainer);  break;
        case 6: middleRight(bannerContainer);   break;
        case 7: bottomLeft(bannerContainer);    break;
        case 8: bottomCenter(bannerContainer);  break;
        case 9: bottomRight(bannerContainer);   break;
        default: topCenter(bannerContainer);    break;
      }
      
      [PokktAds showAd:screenId withViewController:getRootViewController() bannerContainer:bannerContainer withDelegate:adapter];
      return;
    }
    //load banner with given rect
    else if([jsonObject objectForKey:@"width"] != nil || [jsonObject objectForKey:@"height"] != nil) {
      
      int width = [jsonObject[@"width"] intValue];
      int height = [jsonObject[@"height"] intValue];
      float x = [jsonObject[@"x"] floatValue];
      float y = [jsonObject[@"y"]floatValue];
      
      if (bannerContainer != NULL)
      {
        [PokktAds destroyBanner:bannerContainer];
        bannerContainer = NULL;
      }
      
      bannerContainer = [[PokktBannerView alloc] initWithFrame:CGRectMake(x, y, width, height)];
      [getRootViewController().view addSubview:bannerContainer];
      
      [PokktAds showAd:screenId withViewController:getRootViewController() bannerContainer:bannerContainer withDelegate:adapter];
      return;
    }
    //show full screen ad
    else {
      [PokktAds showAd:screenId withViewController:getRootViewController() withDelegate:adapter];
      return;
    }
  }
  
  if ([BANNER_DESTROY isEqualToString:operation]) {
    [PokktAds destroyBanner:bannerContainer];
    return;
  }
  
  // Debugging APIs
  if ([DEBUGGING_SHOULD_DEBUG isEqualToString:operation]) {
    [PokktDebugger setDebug:[params boolValue]];
    return;
  }
  
  if ([DEBUGGING_SHOW_LOG isEqualToString:operation]) {
    [PokktDebugger printLog:params];
    return;
  }
  
  if ([DEBUGGING_SHOW_TOAST isEqualToString:operation]) {
    [PokktDebugger showToast:params viewController:getRootViewController()];
    return;
  }
  
  // Data access consent
  if ([SET_DATA_ACCESS_CONSENT isEqualToString:operation]) {
    [PokktAds setPokktConsentInfo:getConsentInfoFromJSONString(params)];
    return;
  }
  
  NSLog(@"[POKKT-OBJC] Unknown operation requested: %@", operation);
}

#pragma mark - PokktAdDelegate Implementation

- (void)adCachingResult:(NSString *)screenId isSuccess:(BOOL)success withReward:(double)reward errorMessage:(NSString *)errorMessage
{
    NSMutableDictionary *additionalParams = [[NSMutableDictionary alloc] init];
    additionalParams[@"SCREEN_ID"] = screenId;
    additionalParams[@"IS_SUCCESS"] = BOOL_TO_STRING(success);
    additionalParams[@"REWARD"] = [[NSNumber numberWithFloat:reward] stringValue];
    additionalParams[@"ERROR_MESSAGE"] = errorMessage;
    
    NSString *params = stringifyJSONDictionary(additionalParams);
    notifyFramework(EVENT_AD_CACHING_RESULT, params);
}

- (void)adDisplayResult:(NSString *)screenId isSuccess:(BOOL)success errorMessage:(NSString *)errorMessage {
    NSMutableDictionary *additionalParams = [[NSMutableDictionary alloc] init];
    additionalParams[@"SCREEN_ID"] = screenId;
    additionalParams[@"IS_SUCCESS"] = BOOL_TO_STRING(success);
    additionalParams[@"ERROR_MESSAGE"] = errorMessage;
    
    NSString *params = stringifyJSONDictionary(additionalParams);
    notifyFramework(EVENT_AD_DISPLAYED_RESULT, params);
}

- (void)adClosed:(NSString *)screenId adCompleted:(BOOL)adCompleted
{
    NSMutableDictionary *additionalParams = [[NSMutableDictionary alloc] init];
    additionalParams[@"SCREEN_ID"] = screenId;
    additionalParams[@"AD_COMPLETED"] = BOOL_TO_STRING(adCompleted);
    
    NSString *params = stringifyJSONDictionary(additionalParams);
    notifyFramework(EVENT_AD_CLOSED, params);
}

- (void)adClicked:(NSString *)screenId
{
    NSMutableDictionary *additionalParams = [[NSMutableDictionary alloc] init];
    additionalParams[@"SCREEN_ID"] = screenId;
    
    NSString *params = stringifyJSONDictionary(additionalParams);
    notifyFramework(EVENT_AD_CLICKED, params);
}

- (void)adGratified:(NSString *)screenId withReward:(double)reward
{
    NSMutableDictionary *additionalParams = [[NSMutableDictionary alloc] init];
    additionalParams[@"SCREEN_ID"] = screenId;
    additionalParams[@"REWARD"] = [[NSNumber numberWithFloat:reward] stringValue];
    
    NSString *params = stringifyJSONDictionary(additionalParams);
    notifyFramework(EVENT_AD_GRATIFIED, params);
}


#pragma mark - BannerAdDelegate Implementation

- (void)bannerLoaded:(NSString *)screenId
{
    NSMutableDictionary *additionalParams = [[NSMutableDictionary alloc] init];
    additionalParams[@"SCREEN_ID"] = screenId;
    additionalParams[@"ISSUCCESS"] = BOOL_TO_STRING(true);
    additionalParams[@"ERROR_MESSAGE"] = @"";
    NSString *params = stringifyJSONDictionary(additionalParams);
    
    notifyFramework(EVENT_AD_DISPLAYED_RESULT, params);
}

- (void)bannerLoadFailed:(NSString *)screenId errorMessage:(NSString *)errorMessage
{
    NSMutableDictionary *additionalParams = [[NSMutableDictionary alloc] init];
    additionalParams[@"SCREEN_ID"] = screenId;
    additionalParams[@"ISSUCCESS"] = BOOL_TO_STRING(false);
    additionalParams[@"ERROR_MESSAGE"] = errorMessage;
    NSString *params = stringifyJSONDictionary(additionalParams);
    
    notifyFramework(EVENT_AD_DISPLAYED_RESULT, params);
}

- (void)bannerCollapsed:(NSString *)screenId
{
    NSMutableDictionary *additionalParams = [[NSMutableDictionary alloc] init];
    additionalParams[@"SCREEN_ID"] = screenId;
    NSString *params = stringifyJSONDictionary(additionalParams);
    
    notifyFramework(EVENT_BANNER_COLLAPSED, params);
}

- (void)bannerExpanded:(NSString *)screenId
{
    NSMutableDictionary *additionalParams = [[NSMutableDictionary alloc] init];
    additionalParams[@"SCREEN_ID"] = screenId;
    NSString *params = stringifyJSONDictionary(additionalParams);
    
    notifyFramework(EVENT_BANNER_EXPANDED, params);
}

- (void)bannerResized:(NSString *)screenId
{
    NSMutableDictionary *additionalParams = [[NSMutableDictionary alloc] init];
    additionalParams[@"SCREEN_ID"] = screenId;
    NSString *params = stringifyJSONDictionary(additionalParams);
    
    notifyFramework(EVENT_BANNER_RESIZED, params);
}

@end


#pragma mark - UTILS

UIViewController* getRootViewController()
{
    UIViewController *viewController = [[[UIApplication sharedApplication] keyWindow] rootViewController];
    return viewController;
}

NSDictionary* extractJSON(NSString* jsonString)
{
    NSError* jsonError;
    NSData* jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary* jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData
                                                               options:NSJSONReadingMutableContainers
                                                                 error:&jsonError];
    return jsonObject;
}

PokktAdPlayerViewConfig* getAdPlayerViewConfigFromJSONString(NSString* configString)
{
    NSDictionary* jsonObject = extractJSON(configString);
    
    PokktAdPlayerViewConfig* config = [[PokktAdPlayerViewConfig alloc] init];
    
    config.shouldAllowSkip = [jsonObject[@"shouldAllowSkip"] boolValue];
    config.defaultSkipTime = [jsonObject[@"defaultSkipTime"] floatValue];
    config.skipConfirmMessage = jsonObject[@"skipConfirmMessage"];
    config.shouldAllowMute = [jsonObject[@"shouldAllowMute"] boolValue];
    config.shouldConfirmSkip = [jsonObject[@"shouldSkipConfirm"] boolValue];
    config.shouldCollectFeedback = [jsonObject[@"shouldCollectFeedback"] boolValue];
    config.isAudioEnabled = [jsonObject[@"isAudioEnabled"] boolValue];
    config.skipConfirmYesLabel = jsonObject[@"skipConfirmYesLabel"];
    config.skipConfirmNoLabel = jsonObject[@"skipConfirmNoLabel"];
    config.skipTimerMessage = jsonObject[@"skipTimerMessage"];
    config.incentiveMessage = jsonObject[@"incentiveMessage"];
    
    return config;
}

PokktUserInfo* getUserDetailsFromJSONString(NSString* stringData)
{
    NSDictionary *jsonObject = extractJSON(stringData);
    
    PokktUserInfo *info = [[PokktUserInfo alloc] init];
    
    info.name = jsonObject[@"name"];
    info.age = jsonObject[@"age"];
    info.sex = jsonObject[@"sex"];
    info.mobileNumber = jsonObject[@"mobileNo"];
    info.emailAddress = jsonObject[@"emailAddress"];
    info.location = jsonObject[@"location"];
    info.birthday = jsonObject[@"birthday"];
    info.maritalStatus = jsonObject[@"maritalStatus"];
    info.facebookId = jsonObject[@"facebookId"];
    info.twitterHandle = jsonObject[@"twitterHandle"];
    info.educationInformation = jsonObject[@"education"];
    info.nationality = jsonObject[@"nationality"];
    info.employmentStatus = jsonObject[@"employment"];
    info.maturityRating = jsonObject[@"maturityRating"];
    
    return info;
}

PokktConsentInfo* getConsentInfoFromJSONString(NSString* stringData)
{
    NSDictionary *jsonObject = extractJSON(stringData);
    
    PokktConsentInfo* info = [[PokktConsentInfo alloc] init];
    [info setIsGDPRApplicable:[jsonObject[@"GDPRApplicable"] boolValue]];
    [info setIsGDPRConsentAvailable:[jsonObject[@"GDPRConsentAvailable"] boolValue]];
    
    [PokktDebugger printLog:[NSString stringWithFormat:@"GDPRApplicable: %@, GDPRConsentAvailable: %@",
                             info.isGDPRApplicable ? @"true" : @"false", info.isGDPRConsentAvailable ? @"true" : @"false"]];
    
    return info;
}

NSString* stringifyJSONDictionary(NSDictionary *jsonObject)
{
    NSError *jsonError;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonObject options:0 error:&jsonError];
    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    return jsonString;
}

NSLayoutConstraint* getLayoutConstraint(UIView* view, NSLayoutAttribute layoutAttribute1, NSLayoutRelation layoutRelation, UIView* toItem, NSLayoutAttribute layoutAttribute2, CGFloat multiplier, CGFloat constant)
{
    return [NSLayoutConstraint constraintWithItem:view
                                        attribute:layoutAttribute1
                                        relatedBy:layoutRelation
                                           toItem:toItem
                                        attribute:layoutAttribute2
                                       multiplier:multiplier
                                         constant:constant];
}

void updateBannerLocation(UIView* view, NSLayoutConstraint* leading, NSLayoutConstraint* bottom, NSLayoutConstraint* trailing, NSLayoutConstraint* height)
{
    [view addConstraint:trailing];
    [view.superview addConstraint:bottom];
    [view.superview addConstraint:leading];
    [view addConstraint:height];
}

//Top
void topLeft(UIView* view)
{
    NSLayoutConstraint* leading = getLayoutConstraint(view, NSLayoutAttributeLeft, NSLayoutRelationEqual, view.superview, NSLayoutAttributeLeft, 1.0f, 0.f);
    NSLayoutConstraint* bottom = getLayoutConstraint(view, NSLayoutAttributeTop, NSLayoutRelationEqual, view.superview, NSLayoutAttributeTop, 1.0f, 0.f);
    NSLayoutConstraint* trailing = getLayoutConstraint(view, NSLayoutAttributeWidth, NSLayoutRelationEqual, nil, NSLayoutAttributeWidth, 1.0f, 320);
    NSLayoutConstraint* height = getLayoutConstraint(view, NSLayoutAttributeHeight, NSLayoutRelationEqual, nil, NSLayoutAttributeNotAnAttribute, 0, 50);
    
    updateBannerLocation(view, leading, bottom, trailing, height);
}

void topRight(UIView * view)
{
    NSLayoutConstraint* leading = getLayoutConstraint(view, NSLayoutAttributeRight, NSLayoutRelationEqual, view.superview, NSLayoutAttributeRight, 1.0f, 0.f);
    NSLayoutConstraint* bottom = getLayoutConstraint(view, NSLayoutAttributeTop, NSLayoutRelationEqual, view.superview, NSLayoutAttributeTop, 1.0f, 0.f);
    NSLayoutConstraint* trailing = getLayoutConstraint(view, NSLayoutAttributeWidth, NSLayoutRelationEqual, nil, NSLayoutAttributeWidth, 1.0f, 320);
    NSLayoutConstraint* height = getLayoutConstraint(view, NSLayoutAttributeHeight, NSLayoutRelationEqual, nil, NSLayoutAttributeNotAnAttribute, 0, 50);
    
    updateBannerLocation(view, leading, bottom, trailing, height);
}

void topCenter(UIView * view)
{
    NSLayoutConstraint* leading = getLayoutConstraint(view, NSLayoutAttributeCenterX, NSLayoutRelationEqual, view.superview, NSLayoutAttributeCenterX, 1.0f, 0.f);
    NSLayoutConstraint* bottom = getLayoutConstraint(view, NSLayoutAttributeTop, NSLayoutRelationEqual, view.superview, NSLayoutAttributeTop, 1.0f, 0.f);
    NSLayoutConstraint* trailing = getLayoutConstraint(view, NSLayoutAttributeWidth, NSLayoutRelationEqual, nil, NSLayoutAttributeWidth, 1.0f, 320);
    NSLayoutConstraint* height = getLayoutConstraint(view, NSLayoutAttributeHeight, NSLayoutRelationEqual, nil, NSLayoutAttributeNotAnAttribute, 0, 50);
    
    updateBannerLocation(view, leading, bottom, trailing, height);
}

// Middle
void middleLeft(UIView* view)
{
    NSLayoutConstraint* leading = getLayoutConstraint(view, NSLayoutAttributeLeft, NSLayoutRelationEqual, view.superview, NSLayoutAttributeLeft, 1.0f, 0.f);
    NSLayoutConstraint* bottom = getLayoutConstraint(view, NSLayoutAttributeCenterY, NSLayoutRelationEqual, view.superview, NSLayoutAttributeCenterY, 1.0f, 0.f);
    NSLayoutConstraint* trailing = getLayoutConstraint(view, NSLayoutAttributeWidth, NSLayoutRelationEqual, nil, NSLayoutAttributeWidth, 1.0f, 320);
    NSLayoutConstraint* height = getLayoutConstraint(view, NSLayoutAttributeHeight, NSLayoutRelationEqual, nil, NSLayoutAttributeNotAnAttribute, 0, 50);
    
    updateBannerLocation(view, leading, bottom, trailing, height);
}

void middleRight(UIView * view)
{
    NSLayoutConstraint* leading = getLayoutConstraint(view, NSLayoutAttributeRight, NSLayoutRelationEqual, view.superview, NSLayoutAttributeRight, 1.0f, 0.f);
    NSLayoutConstraint* bottom = getLayoutConstraint(view, NSLayoutAttributeCenterY, NSLayoutRelationEqual, view.superview, NSLayoutAttributeCenterY, 1.0f, 0.f);
    NSLayoutConstraint* trailing = getLayoutConstraint(view, NSLayoutAttributeWidth, NSLayoutRelationEqual, nil, NSLayoutAttributeWidth, 1.0f, 320);
    NSLayoutConstraint* height = getLayoutConstraint(view, NSLayoutAttributeHeight, NSLayoutRelationEqual, nil, NSLayoutAttributeNotAnAttribute, 0, 50);
    
    updateBannerLocation(view, leading, bottom, trailing, height);
}

void middleCenter(UIView * view)
{
    NSLayoutConstraint* leading = getLayoutConstraint(view, NSLayoutAttributeCenterX, NSLayoutRelationEqual, view.superview, NSLayoutAttributeCenterX, 1.0f, 0.f);
    NSLayoutConstraint* bottom = getLayoutConstraint(view, NSLayoutAttributeCenterY, NSLayoutRelationEqual, view.superview, NSLayoutAttributeCenterY, 1.0f, 0.f);
    NSLayoutConstraint* trailing = getLayoutConstraint(view, NSLayoutAttributeWidth, NSLayoutRelationEqual, nil, NSLayoutAttributeWidth, 1.0f, 320);
    NSLayoutConstraint* height = getLayoutConstraint(view, NSLayoutAttributeHeight, NSLayoutRelationEqual, nil, NSLayoutAttributeNotAnAttribute, 0, 50);
    
    updateBannerLocation(view, leading, bottom, trailing, height);
}

//Bottom
void bottomLeft(UIView * view)
{
    NSLayoutConstraint* leading = getLayoutConstraint(view, NSLayoutAttributeLeading, NSLayoutRelationEqual, view.superview, NSLayoutAttributeLeading, 1.0f, 0.f);
    NSLayoutConstraint* bottom = getLayoutConstraint(view, NSLayoutAttributeBottom, NSLayoutRelationEqual, view.superview, NSLayoutAttributeBottom, 1.0f, 0.f);
    NSLayoutConstraint* trailing = getLayoutConstraint(view, NSLayoutAttributeWidth, NSLayoutRelationEqual, nil, NSLayoutAttributeWidth, 1.0f, 320);
    NSLayoutConstraint* height = getLayoutConstraint(view, NSLayoutAttributeHeight, NSLayoutRelationEqual, nil, NSLayoutAttributeNotAnAttribute, 0, 50);
    
    updateBannerLocation(view, leading, bottom, trailing, height);
}

void bottomRight(UIView * view)
{
    NSLayoutConstraint* leading = getLayoutConstraint(view, NSLayoutAttributeRight, NSLayoutRelationEqual, view.superview, NSLayoutAttributeRight, 1.0f, 0.f);
    NSLayoutConstraint* bottom = getLayoutConstraint(view, NSLayoutAttributeBottom, NSLayoutRelationEqual, view.superview, NSLayoutAttributeBottom, 1.0f, 0.f);
    NSLayoutConstraint* trailing = getLayoutConstraint(view, NSLayoutAttributeWidth, NSLayoutRelationEqual, nil, NSLayoutAttributeWidth, 1.0f, 320);
    NSLayoutConstraint* height = getLayoutConstraint(view, NSLayoutAttributeHeight, NSLayoutRelationEqual, nil, NSLayoutAttributeNotAnAttribute, 0, 50);
    
    updateBannerLocation(view, leading, bottom, trailing, height);
}

void bottomCenter(UIView * view)
{
    NSLayoutConstraint* leading = getLayoutConstraint(view, NSLayoutAttributeCenterX, NSLayoutRelationEqual, view.superview, NSLayoutAttributeCenterX, 1.0f, 0.f);
    NSLayoutConstraint* bottom = getLayoutConstraint(view, NSLayoutAttributeBottom, NSLayoutRelationEqual, view.superview, NSLayoutAttributeBottom, 1.0f, 0.f);
    NSLayoutConstraint* trailing = getLayoutConstraint(view, NSLayoutAttributeWidth, NSLayoutRelationEqual, nil, NSLayoutAttributeWidth, 1.0f, 320);
    NSLayoutConstraint* height = getLayoutConstraint(view, NSLayoutAttributeHeight, NSLayoutRelationEqual, nil, NSLayoutAttributeNotAnAttribute, 0, 50);
    
    updateBannerLocation(view, leading, bottom, trailing, height);
}


#pragma mark - POKKT-TO-FRAMEWORK

@interface PokktPlugin : NSObject <RCTBridgeModule>
@end

@implementation PokktPlugin
RCT_EXPORT_MODULE();
RCT_REMAP_METHOD(execute,
                 operation:(NSString *)operation params:(NSString *)params
                 callback: (RCTResponseSenderBlock)callback)
{
    if ([@"getSDKVersion" isEqualToString:operation]) {
        NSString *sdkVersion = [PokktAds getSDKVersion];
        callback(@[sdkVersion]);
        return;
    }
    
    if ([@"isAdCached" isEqualToString:operation]) {
        NSError* jsonError;
        NSData* jsonData = [params dataUsingEncoding:NSUTF8StringEncoding];
        NSDictionary* jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData
                                                                   options:NSJSONReadingMutableContainers
                                                                     error:&jsonError];
        NSString *screenId = jsonObject[@"screenId"];
        BOOL isAdAvailable = [PokktAds isAdCached:screenId];
        callback(@[isAdAvailable ? @"true" : @"false"]);
        return;
    }
    
    notifyNative(operation, params);
}
@end
