#import "AdinCubeBridge.h"

#import "AdinCube.h"
#import "AdinCubeBannerImpl.h"
#import "ContextAwareAdinCubeInterstitialDelegate.h"
#import "ContextAwareAdinCubeBannerDelegate.h"
#import "ContextAwareAdinCubeRewardedDelegate.h"
#import "ContextAwareAdinCubeUserConsentDelegate.h"

@interface AdinCubeBridge()

@property (retain) ContextAwareAdinCubeInterstitialDelegate* interstitialDelegate;
@property (retain) ContextAwareAdinCubeBannerDelegate* bannerDelegate;
@property (retain) ContextAwareAdinCubeRewardedDelegate* rewardedDelegate;
@property (retain) ContextAwareAdinCubeUserConsentDelegate* userConsentDelegate;

@end

@implementation AdinCubeBridge

@synthesize interstitialDelegate;
@synthesize bannerDelegate;
@synthesize rewardedDelegate;
@synthesize userConsentDelegate;

- (void)sendResult:(NSString*)result forAction:(NSString*)action AndCommand:(CDVInvokedUrlCommand*)command {
    CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:[NSString stringWithFormat:@"%@-%@", action, result]];
    [pluginResult setKeepCallbackAsBool: TRUE];
    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

- (void)sendBoolResult:(BOOL)result forAction:(NSString*)action AndCommand:(CDVInvokedUrlCommand*)command {
    NSString* sResult = (result)?@"true":@"false";
    [self sendResult:sResult forAction:action AndCommand:command];
}

- (void)success:(CDVInvokedUrlCommand*)command {
    CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
    [pluginResult setKeepCallbackAsBool: TRUE];
    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];    
}

- (void)error:(CDVInvokedUrlCommand*)command {
    CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
    [pluginResult setKeepCallbackAsBool: TRUE];
    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];    
}

- (void)storeCallbackContext:(CDVInvokedUrlCommand*)command  {
    interstitialDelegate = [[ContextAwareAdinCubeInterstitialDelegate alloc] initWithPlugin:self command:command];
    [AdinCube.Interstitial setDelegate:interstitialDelegate];

    bannerDelegate = [[ContextAwareAdinCubeBannerDelegate alloc] initWithPlugin:self command:command];
    [[AdinCubeBannerImpl sharedBanner] setDelegate:bannerDelegate];

    rewardedDelegate = [[ContextAwareAdinCubeRewardedDelegate alloc] initWithPlugin:self command:command];
    [AdinCube.Rewarded setDelegate:rewardedDelegate];

    userConsentDelegate = [[ContextAwareAdinCubeUserConsentDelegate alloc] initWithPlugin:self command:command];
    [AdinCube.UserConsent setAskDelegate:userConsentDelegate];
    [AdinCube.UserConsent setEditDelegate:userConsentDelegate];
}

- (void)interstitial_init:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    [AdinCube.Interstitial initialize];
    
    [self success:command];
}

- (void)interstitial_isReady:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    BOOL bIsReady = [AdinCube.Interstitial isReady];

    [self sendBoolResult:bIsReady forAction:@"interstitial_isReady" AndCommand:command];
    [self success:command];
}

- (void)interstitial_show:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext: command];

    [AdinCube.Interstitial show:self.viewController];

    [self success:command];
}

- (void)banner_setRespectSafeArea:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    [[AdinCubeBannerImpl sharedBanner] setRespectSafeArea:[[command.arguments objectAtIndex:1] boolValue] atPosition:[command.arguments objectAtIndex:0]];

    [self success:command];
}

- (void)banner_load:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    [[AdinCubeBannerImpl sharedBanner] load:[command.arguments objectAtIndex:0] atPosition:[command.arguments objectAtIndex:1] rootViewController:self.viewController];

    [self success:command];
}

- (void)banner_show:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    [[AdinCubeBannerImpl sharedBanner] show:[command.arguments objectAtIndex:0] atPosition:[command.arguments objectAtIndex:1] rootViewController:self.viewController];

    [self success:command];
}

- (void)banner_hide:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext: command];

    [[AdinCubeBannerImpl sharedBanner] hide:self.viewController];

    [self success:command];
}

- (void)banner_setVisible:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext: command];

    BOOL visible = [[command.arguments objectAtIndex:0] boolValue];
    [[AdinCubeBannerImpl sharedBanner] setVisible:visible rootViewController:self.viewController];

    [self success:command];
}

- (void)banner_getSize:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext: command];

    int width = [[AdinCubeBannerImpl sharedBanner] width:self.viewController];
    int height = [[AdinCubeBannerImpl sharedBanner] height:self.viewController];

    [self sendResult:[NSString stringWithFormat:@"%dx%d", width, height] forAction:@"banner_getSize" AndCommand:command];
    [self success:command];
}

- (void)rewarded_fetch:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    [AdinCube.Rewarded fetch];

    [self success:command];  
}

- (void)rewarded_isReady:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    [self sendBoolResult:[AdinCube.Rewarded isReady] forAction:@"rewarded_isReady" AndCommand:command];

    [self success:command];
}

- (void)rewarded_show:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    [AdinCube.Rewarded show:self.viewController];

    [self success:command];
}

- (void)userconsent_ask:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    [AdinCube.UserConsent ask:self.viewController];

    [self success:command];
}

- (void)userconsent_edit:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    [AdinCube.UserConsent edit:self.viewController];

    [self success:command];
}

- (void)userconsent_isAccepted:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    NSString* vendorSlug = [command.arguments objectAtIndex:0];
    BOOL bIsAccepted = [AdinCube.UserConsent isAccepted:vendorSlug];

    [self sendBoolResult:bIsAccepted forAction:@"userconsent_isAccepted" AndCommand:command];
    [self success:command];
}

- (void)userconsent_isPurposeAccepted:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    NSString* sPurpose = [command.arguments objectAtIndex:0];
    int purpose = [self purposeForName:sPurpose];
    BOOL bIsPurposeAccepted = NO;
    if (purpose != -1) {
        bIsPurposeAccepted = [AdinCube.UserConsent isPurposeAccepted:(AdinCubeUserConsentPurpose)purpose];
    }

    [self sendBoolResult:bIsPurposeAccepted forAction:@"userconsent_isPurposeAccepted" AndCommand:command];
    [self success:command];
}

- (int)purposeForName:(NSString*)purpose {
    if ([@"INFORMATION" isEqualToString:purpose]) {
        return AdinCubeUserConsentPurposeInformation;
    }
    if ([@"PERSONALISATION" isEqualToString:purpose]) {
        return AdinCubeUserConsentPurposePersonalisation;
    }
    if ([@"AD" isEqualToString:purpose]) {
        return AdinCubeUserConsentPurposeAd;
    }
    if ([@"CONTENT" isEqualToString:purpose]) {
        return AdinCubeUserConsentPurposeContent;
    }
    if ([@"MEASUREMENT" isEqualToString:purpose]) {
        return AdinCubeUserConsentPurposeMeasurement;
    }
    return -1;
}

- (void)userconsent_getIABConsentString:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    NSString* consentString = [AdinCube.UserConsent getIABConsentString];

    [self sendResult:consentString forAction:@"userconsent_getIABConsentString" AndCommand:command];
    [self success:command];
}

- (void)userconsent_gdprApplies:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    bool gdprApplies = AdinCube.UserConsent.gdprApplies;

    [self sendBoolResult:gdprApplies forAction:@"userconsent_gdprApplies" AndCommand:command];
    [self success:command];
}

- (void)userconsent_external_setConsent:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    NSString* iabString = [command.arguments objectAtIndex:0];
    NSArray* nonIABVendorsAccepted = nil;
    if (command.arguments.count > 1 && ![[command.arguments objectAtIndex:1] isKindOfClass:[NSNull class]]) {
        nonIABVendorsAccepted = [command.arguments objectAtIndex:1];
    }
    [AdinCube.UserConsent.External setConsentWithIABString:iabString andNonIABVendorsAccepted:nonIABVendorsAccepted];

    [self success:command];
}

- (void)userinfo_setAge:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    NSUInteger age = [[command.arguments objectAtIndex:0] unsignedIntegerValue];
    [AdinCube UserInfo].age = age;

    [self success:command];
}

- (void)userinfo_setGender:(CDVInvokedUrlCommand*)command {
    static NSDictionary* genderMap = nil;
    if (genderMap == nil) {
        genderMap = @{
            @"MALE": [NSNumber numberWithInt:AdinCubeUserInfoGenderMale],
            @"FEMALE": [NSNumber numberWithInt:AdinCubeUserInfoGenderFemale]
        };
    }

    [self storeCallbackContext:command];

    NSString* sGender = [command.arguments objectAtIndex:0];
    NSNumber* gender = [genderMap objectForKey:sGender];
    if (gender != nil) {
        [AdinCube UserInfo].gender = [gender intValue];
    }

    [self success:command];
}

- (void)userinfo_setMaritalStatus:(CDVInvokedUrlCommand*)command {
    static NSDictionary* maritalStatusMap = nil;
    if (maritalStatusMap == nil) {
        maritalStatusMap = @{
            @"SINGLE": [NSNumber numberWithInt:AdinCubeUserInfoMaritalStatusSingle],
            @"MARRIED": [NSNumber numberWithInt:AdinCubeUserInfoMaritalStatusMarried]
        };
    }

    [self storeCallbackContext:command];

    NSString* sMaritalStatus = [command.arguments objectAtIndex:0];
    NSNumber* maritalStatus = [maritalStatusMap objectForKey:sMaritalStatus];
    if (maritalStatus != nil) {
        [AdinCube UserInfo].maritalStatus = [maritalStatus intValue];
    }

    [self success:command];
}

- (void)userinfo_setLocation:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    double latitude = [[command.arguments objectAtIndex:0] doubleValue];
    double longitude = [[command.arguments objectAtIndex:1] doubleValue];

    [[AdinCube UserInfo] setLatitude:latitude andLongitude:longitude];

    [self success:command];
}

- (void)logNative:(CDVInvokedUrlCommand*)command {
	if([command.arguments count] > 0 && [[command.arguments objectAtIndex:0] isKindOfClass:[NSString class]]) {
		NSLog(@"%@", [command.arguments objectAtIndex:0]);
	}
	[self storeCallbackContext:command];
    [self success:command];
}

- (void)toastNative:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];
    [self success:command];   
}

- (void)setAppKey:(CDVInvokedUrlCommand*)command {
    [self storeCallbackContext:command];

    [AdinCube setAppKey:[command.arguments objectAtIndex:0]];

    [self success:command];
}

@end