//
//  SMAMoPubSmaatoBannerAdapter.m
//  SmaatoSDKAdapters
//
//  Created by Smaato Inc on 29.10.18.
//  Copyright © 2018 Smaato Inc. All rights reserved.￼
//  Licensed under the Smaato SDK License Agreement￼
//  https://www.smaato.com/sdk-license-agreement/
//

#import <SmaatoSDKBanner/SmaatoSDKBanner.h>
#import "SMAMoPubSmaatoBannerAdapter.h"
#if __has_include("MoPub.h")
#import "MPLogging.h"
#endif

static NSString *const kSMAMoPubCustomEventInfoAdSpaceIdKey = @"adspaceId";
static NSString *const kSMAMoPubBannerAdapterVersion = @"1.0.1";

@interface SMAMoPubSmaatoBannerAdapter () <SMABannerViewDelegate>
@property (nonatomic) SMABannerView *bannerView;
@property (nonatomic, copy) NSString *adSpaceId;
@end

@implementation SMAMoPubSmaatoBannerAdapter

+ (NSString *)version
{
    return kSMAMoPubBannerAdapterVersion;
}

- (void)requestAdWithSize:(CGSize)size customEventInfo:(NSDictionary *)info
{
    // Passing mediation information
    SMABannerView.mediationNetworkName = NSStringFromClass([self class]);
    SMABannerView.mediationAdapterVersion = kSMAMoPubBannerAdapterVersion;
    SMABannerView.mediationNetworkSDKVersion = [[MoPub sharedInstance] version];

    // Convert ad size format
    SMABannerAdSize convertedAdSize = [self SMABannerAdSizeFromRequestedSize:size];

    // Extract ad space information
    self.adSpaceId = [self fetchValueForKey:kSMAMoPubCustomEventInfoAdSpaceIdKey fromEventInfo:info];

    // Verify ad space information
    if (![self checkCredentialsWithAdSpaceId:self.adSpaceId]) {
        return;
    }

    // Create and configure ad view object
    self.bannerView = [[SMABannerView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, size.width, size.height)];
    self.bannerView.delegate = self;
    self.bannerView.autoreloadInterval = kSMABannerAutoreloadIntervalDisabled;

    // Pass user location
    CLLocation *location = self.delegate.location;
    if (location) {
        SMALocation *userLocation = [[SMALocation alloc] initWithLatitude:location.coordinate.latitude
                                                                longitude:location.coordinate.longitude
                                                       horizontalAccuracy:location.horizontalAccuracy
                                                                timestamp:location.timestamp];
        SmaatoSDK.userLocation = userLocation;
    }

    /**
     Optional:
     You can also set specific user profile targeting parameters here.
     Please check the Smaato wiki for all available properties and further details.

     Examples:
     SmaatoSDK.userAge = 30;
     SmaatoSDK.userGender = kSMAGenderMale;
     */

    // Load ad
    MPLogAdEvent([MPLogEvent adLoadAttemptForAdapter:SMABannerView.mediationNetworkName dspCreativeId:nil dspName:nil],
                 [self getAdNetworkId]);
    [self.bannerView loadWithAdSpaceId:self.adSpaceId adSize:convertedAdSize];
}

- (NSString *)fetchValueForKey:(NSString *)definedKey fromEventInfo:(NSDictionary *)info
{
    __block NSString *value;
    [info enumerateKeysAndObjectsUsingBlock:^(NSString *_Nonnull key, id _Nonnull obj, BOOL *_Nonnull stop) {
        if ([definedKey caseInsensitiveCompare:key] == NSOrderedSame) {
            value = obj;
            *stop = YES;
        }
    }];
    return value;
}

- (SMABannerAdSize)SMABannerAdSizeFromRequestedSize:(CGSize)requestedSize
{
    if (CGSizeEqualToSize(requestedSize, MOPUB_BANNER_SIZE)) {
        return kSMABannerAdSizeXXLarge_320x50;
    } else if (CGSizeEqualToSize(requestedSize, MOPUB_MEDIUM_RECT_SIZE)) {
        return kSMABannerAdSizeMediumRectangle_300x250;
    } else if (CGSizeEqualToSize(requestedSize, MOPUB_LEADERBOARD_SIZE)) {
        return kSMABannerAdSizeLeaderboard_728x90;
    } else if (CGSizeEqualToSize(requestedSize, MOPUB_WIDE_SKYSCRAPER_SIZE)) {
        return kSMABannerAdSizeSkyscraper_120x600;
    } else {
        return kSMABannerAdSizeAny;
    }
}

- (BOOL)checkCredentialsWithAdSpaceId:(NSString *)adSpaceId
{
    if (adSpaceId) {
        return YES;
    }

    NSString *errorMessage = @"AdSpaceId can not be extracted. Please check your configuration on MoPub dashboard.";
    MPLogInfo(@"[SmaatoSDK] [Error] %@: %@", SMABannerView.mediationNetworkName, errorMessage);

    if ([self.delegate respondsToSelector:@selector(bannerCustomEvent:didFailToLoadAdWithError:)]) {
        NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : errorMessage };
        NSError *error = [NSError errorWithDomain:SMABannerView.mediationNetworkName code:kSMAErrorCodeInvalidRequest userInfo:userInfo];

        [self.delegate bannerCustomEvent:self didFailToLoadAdWithError:error];
    }

    return NO;
}

- (NSString *)getAdNetworkId
{
    return self.adSpaceId;
}

- (BOOL)enableAutomaticImpressionAndClickTracking
{
    return NO;
}

#pragma mark - SMABannerViewDelegate

- (UIViewController *)presentingViewControllerForBannerView:(SMABannerView *)bannerView
{
    return self.delegate.viewControllerForPresentingModalView;
}

- (void)bannerViewDidLoad:(SMABannerView *)bannerView
{
    MPLogAdEvent([MPLogEvent adLoadSuccessForAdapter:SMABannerView.mediationNetworkName], [self getAdNetworkId]);
    MPLogAdEvent([MPLogEvent adShowAttemptForAdapter:SMABannerView.mediationNetworkName], [self getAdNetworkId]);
    MPLogAdEvent([MPLogEvent adShowSuccessForAdapter:SMABannerView.mediationNetworkName], [self getAdNetworkId]);

    if ([self.delegate respondsToSelector:@selector(bannerCustomEvent:didLoadAd:)]) {
        [self.delegate bannerCustomEvent:self didLoadAd:bannerView];
    }
}

- (void)bannerViewDidClick:(SMABannerView *)bannerView
{
    MPLogAdEvent([MPLogEvent adTappedForAdapter:SMABannerView.mediationNetworkName], [self getAdNetworkId]);

    if ([self.delegate respondsToSelector:@selector(trackClick)]) {
        [self.delegate trackClick];
    }
}

- (void)bannerView:(SMABannerView *)bannerView didFailWithError:(NSError *)error
{
    MPLogAdEvent([MPLogEvent adLoadFailedForAdapter:SMABannerView.mediationNetworkName error:error], [self getAdNetworkId]);

    if ([self.delegate respondsToSelector:@selector(bannerCustomEvent:didFailToLoadAdWithError:)]) {
        [self.delegate bannerCustomEvent:self didFailToLoadAdWithError:error];
    }
}

- (void)bannerViewWillPresentModalContent:(SMABannerView *)bannerView
{
    MPLogAdEvent([MPLogEvent adWillPresentModalForAdapter:SMABannerView.mediationNetworkName], [self getAdNetworkId]);

    if ([self.delegate respondsToSelector:@selector(bannerCustomEventWillBeginAction:)]) {
        [self.delegate bannerCustomEventWillBeginAction:self];
    }
}

- (void)bannerViewDidPresentModalContent:(SMABannerView *)bannerView
{
    // No corresponding delegate method from MoPub SDK available.
}

- (void)bannerViewDidDismissModalContent:(SMABannerView *)bannerView
{
    MPLogAdEvent([MPLogEvent adDidDismissModalForAdapter:SMABannerView.mediationNetworkName], [self getAdNetworkId]);

    if ([self.delegate respondsToSelector:@selector(bannerCustomEventDidFinishAction:)]) {
        [self.delegate bannerCustomEventDidFinishAction:self];
    }
}

- (void)bannerWillLeaveApplicationFromAd:(SMABannerView *)bannerView
{
    MPLogAdEvent([MPLogEvent adWillLeaveApplicationForAdapter:SMABannerView.mediationNetworkName], [self getAdNetworkId]);

    if ([self.delegate respondsToSelector:@selector(bannerCustomEventWillLeaveApplication:)]) {
        [self.delegate bannerCustomEventWillLeaveApplication:self];
    }
}

- (void)bannerViewDidTTLExpire:(SMABannerView *)bannerView
{
    NSString *errorMessage = @"Banner TTL has expired.";
    NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : errorMessage };
    NSError *error = [NSError errorWithDomain:SMABannerView.mediationNetworkName code:kSMAErrorCodeNoAdAvailable userInfo:userInfo];

    MPLogAdEvent([MPLogEvent adLoadFailedForAdapter:SMABannerView.mediationNetworkName error:error], [self getAdNetworkId]);

    if ([self.delegate respondsToSelector:@selector(bannerCustomEvent:didFailToLoadAdWithError:)]) {
        [self.delegate bannerCustomEvent:self didFailToLoadAdWithError:error];
    }
}

- (void)bannerViewDidImpress:(SMABannerView *)bannerView
{
    if ([self.delegate respondsToSelector:@selector(trackImpression)]) {
        [self.delegate trackImpression];
    }
}
@end
